К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как в 1С получить город из адреса

Как в 1С получить город из адреса: работа с ФИАС/КЛАДР, функция РаботаСАдресами, разбор строки адреса, контактная информация и проверка результата.

Задача получить город из адреса возникает в 1С постоянно: при формировании отчётов по регионам, расчёте стоимости доставки, маршрутизации документов и выгрузке данных во внешние системы. Сложность в том, что адрес в 1С может храниться в разных форматах — как единая строка «в свободной форме», как структурированные данные по ФИАС или КЛАДР, а также как набор полей в табличной части контактной информации.

Универсального решения «на одну кнопку» не существует: способ извлечения города зависит от того, как именно адрес попал в базу. Если контрагенты вводились аккуратно через адресный классификатор — город легко получить штатными средствами БСП (библиотеки стандартных подсистем). Если адрес вводили вручную строкой, придётся разбирать её программно, и результат будет требовать проверки.

Ниже разобраны рабочие подходы: штатная функция РаботаСАдресами.СведенияОбАдресе(), разбор JSON-представления контактной информации, парсинг произвольной строки и типовые ошибки, которые приводят к пустому или неверному городу.

Как 1С хранит адрес и почему это важно

В типовых конфигурациях (УТ, ERP, Бухгалтерия, ЗУП) адрес хранится в регистре сведений «Контактная информация» в двух видах одновременно: поле Представление — это строка для показа пользователю, а поле Значение (в новых версиях) — JSON-структура с разложенными по полям компонентами адреса. В старых базах вместо JSON используется список значений с полями КЛАДР.

Ключевой момент: если адрес вводился через адресный классификатор (кнопка выбора из ФИАС), JSON содержит отдельные элементы — регион, район, город, населённый пункт, улица, дом. Тогда город извлекается по имени поля без всякого разбора строки. Если же пользователь просто напечатал адрес в поле представления, JSON может быть пустым или содержать только строку целиком.

Поэтому первый шаг любого решения — определить, какая доля адресов в базе структурирована. Это можно сделать запросом: выбрать записи контактной информации с видом «Адрес» и проверить, заполнено ли поле Значение и есть ли в нём элемент с типом «Город».

Способ 1. Штатная функция РаботаСАдресами.СведенияОбАдресе()

В конфигурациях на базе БСП есть модуль РаботаСАдресами (в старых версиях — УправлениеКонтактнойИнформацией). Функция СведенияОбАдресе() принимает адрес в виде строки JSON или списка значений и возвращает структуру с полями: Индекс, Регион, Район, Город, НаселенныйПункт, Улица, Дом, Корпус, Квартира и другие.

Типовой код выглядит так: сначала получаем значение контактной информации объекта, затем передаём его в функцию и читаем нужное поле.

КИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(

КонтрагентСсылка,

Перечисления.ТипыКонтактнойИнформации.Адрес);

Для Каждого СтрокаКИ Из КИ Цикл

Сведения = РаботаСАдресами.СведенияОбАдресе(СтрокаКИ.Значение);

Город = Сведения.Город;

Если ПустаяСтрока(Город) Тогда

Город = Сведения.НаселенныйПункт;

КонецЕсли;

КонецЦикла;

Обратите внимание на подстановку НаселенныйПункт: для адресов в сельской местности поле «Город» пусто, а населённый пункт хранится отдельно. Для городов федерального значения (Москва, Санкт-Петербург, Севастополь) город может совпадать с регионом или находиться в поле НаселенныйПункт — зависит от версии классификатора.

bsl
Сведения = РаботаСАдресами.СведенияОбАдресе(СтрокаКИ.Значение);
Город = ?(ПустаяСтрока(Сведения.Город), Сведения.НаселенныйПункт, Сведения.Город);

Способ 2. Разбор JSON контактной информации вручную

Если по какой-то причине функция БСП недоступна (самописная конфигурация, обрезанная библиотека), JSON можно разобрать напрямую штатным объектом ЧтениеJSON. В структуре адреса город находится в массиве value → элементы area (район), city (город), settlement (населённый пункт) — точные имена зависят от формата, поэтому надёжнее искать по типу элемента.

Чтение = Новый ЧтениеJSON;

Чтение.УстановитьСтроку(СтрокаJSON);

Данные = ПрочитатьJSON(Чтение, Истина);

Чтение.Закрыть();

Город = "";

Если Данные.Получить("city") <> Неопределено Тогда

Город = Данные["city"];

ИначеЕсли Данные.Получить("settlement") <> Неопределено Тогда

Город = Данные["settlement"];

КонецЕсли;

Структура JSON отличается между версиями БСП и форматами (ФИАС, ГАР), поэтому перед промышленным использованием выгрузите несколько реальных адресов из своей базы и посмотрите фактические имена ключей. Полагаться на документацию одной версии при работе с другой — частая причина пустого результата.

Способ 3. Разбор адреса, введённого свободной строкой

Когда адрес хранится только как строка вида «г. Екатеринбург, ул. Ленина, д. 5», структурированных полей нет и приходится разбирать текст. Простейший подход — разделить строку по запятым и искать фрагмент с маркерами «г.», «г », «город», «пгт», «с.», «д.» (деревня) и т.п.

Части = СтрРазделить(ПредставлениеАдреса, ",");

Город = "";

Для Каждого Часть Из Части Цикл

Тест = НРег(СокрЛП(Часть));

Если СтрНачинаетсяС(Тест, "г.") Или СтрНачинаетсяС(Тест, "г ") Тогда

Город = СокрЛП(Часть);

Прервать;

КонецЕсли;

КонецЦикла;

Этот метод эвристический: он ошибается, когда в адресе нет префикса «г.» (просто «Екатеринбург, ул. Ленина»), когда город и регион слиты («Москва, ул. Тверская» — здесь город совпадает с регионом), или когда районный центр указан раньше города. Для массовой обработки такие адреса лучше прогнать через сервис нормализации (например, через API подсказок адресов) и сохранить результат обратно в структурированном виде.

Как выбрать подход под свою ситуацию

Выбор способа определяется двумя факторами: форматом хранения адресов и масштабом задачи. Разовое получение города в отчёте и массовая миграция базы — разные сценарии с разными требованиями к надёжности.

Сравнение способов получения города

СведенияОбАдресе() из БСП

Подходит для типовых конфигураций с адресами, введёнными через классификатор. Точный результат, но требует заполненного поля Значение.

Разбор JSON вручную

Для самописных конфигураций и нестандартных интеграций. Требует знания фактической структуры JSON в вашей базе.

Разбор строки по разделителям

Единственный вариант для адресов в свободной форме. Эвристика: даёт ошибки на нестандартных записях, требует проверки.

Внешний сервис нормализации

Для массовой очистки legacy-данных. Даёт структурированный адрес из любой строки, но требует доступа в интернет и согласования передачи персональных данных.

Для отчётов «на лету» достаточно функции БСП с подстановкой населённого пункта. Для миграции старой базы с адресами строкой разумнее один раз нормализовать данные через сервис и дальше работать только со структурой — это снимет проблему навсегда.

Маршрут решения

Как выбрать действие

Конфигурация типовая, адреса вводили через классификаторИспользуйте РаботаСАдресами.СведенияОбАдресе() и читайте поле Город с подстановкой НаселенныйПункт
Поле Значение в контактной информации пустое, есть только ПредставлениеРазбирайте строку по запятым с поиском маркеров «г.», «пгт», «с.» и проверяйте результат вручную
Нужно обработать тысячи legacy-адресовПрогоните адреса через сервис нормализации и сохраните структуру в поле Значение
Самописная конфигурация без БСПРазбирайте JSON через ЧтениеJSON, предварительно изучив фактические имена ключей в вашей базе

Проверка результата и типичные ошибки

После внедрения любого из способов результат нужно проверить на реальных данных. Возьмите выборку из 20–30 контрагентов из разных регионов, включая города федерального значения, сельские адреса и адреса с районными центрами, и сравните извлечённый город с ожидаемым.

Контрольные точки

Как проверить результат

Город для адресов вида «г. Москва, ул. ...»
Норма

Возвращается «Москва»

Тревожный признак

Пустая строка или «Москва г» дублируется с регионом

Сельский адрес «... обл, ... р-н, с. Иваново»
Норма

Возвращается «Иваново» из поля НаселенныйПункт

Тревожный признак

Пустой город, потому что читается только поле Город

Адрес с районным центром «... обл, г. Каменск-Уральский, ...»
Норма

Город извлечён, район не подставлен вместо города

Тревожный признак

В город попал район или регион

Адрес в свободной форме без префикса «г.»
Норма

Город определён или запись помечена для ручной проверки

Тревожный признак

В город попала улица или индекс

Наиболее частые ошибки при самостоятельной реализации:

Типичные ошибки
01
Чтение только поля Город — для сёл и посёлков результат пустой; всегда подставляйте НаселенныйПункт как запасной вариант.
02
Разбор поля Представление вместо Значение — представление может быть отредактировано пользователем и не соответствовать структуре.
03
Игнорирование городов федерального значения — у Москвы и Санкт-Петербурга город может совпадать с регионом или лежать в другом поле.
04
Поиск подстроки «г.» без учёта регистра и пробелов — «Г.», «г .», «город» пропускаются, часть адресов остаётся необработанной.
05
Массовая перезапись адресов без бэкапа — откатить ошибочную обработку контактной информации очень трудно.

Массовая обработка и производительность

Если город нужен в отчёте по тысячам контрагентов, не вызывайте разбор адреса в цикле по строкам отчёта — это заметно замедлит формирование. Правильнее один раз собрать соответствие «Контрагент → Город» в соответствие (map) или временную таблицу и дальше использовать её.

Для регулярных отчётов по регионам и городам оправдано хранить извлечённый город в дополнительном сведении контрагента и обновлять его регламентным заданием или подпиской на запись контактной информации. Тогда отчёты работают с готовым полем без разбора JSON при каждом формировании.

Порядок внедрения решения
  1. 1
    Проверьте запросом, какая доля адресов имеет заполненное поле Значение (JSON).
  2. 2
    Для структурированных адресов используйте РаботаСАдресами.СведенияОбАдресе() с подстановкой НаселенныйПункт.
  3. 3
    Для адресов строкой добавьте эвристический разбор с пометкой сомнительных записей.
  4. 4
    Проверьте результат на выборке из разных регионов и типов населённых пунктов.
  5. 5
    Вынесите город в дополнительное сведение и обновляйте его подпиской или регламентным заданием.
Перед написанием собственного разбора JSON выгрузите через консоль кода три-четыре реальных значения из регистра КонтактнаяИнформация и посмотрите фактические имена ключей. В разных версиях БСП и форматах ФИАС/ГАР они отличаются, и код, написанный «по документации», нередко возвращает пустые поля.
ПЗ
Практическое замечание

Часто задаваемые вопросы

Почему СведенияОбАдресе() возвращает пустой город, хотя адрес заполнен?

Чаще всего адрес введён вручную строкой, и поле Значение (JSON) не содержит разложенных компонентов — разбирать нечего. Вторая причина: это сельский адрес, где населённый пункт хранится в поле «НаселенныйПункт», а «Город» пуст по определению. Проверьте оба поля и содержимое JSON.

Как получить город в запросе, не используя код?

Штатно в языке запросов разобрать JSON нельзя. Варианты: использовать СКД с вычисляемым полем и функцией из общего модуля, либо хранить город в отдельном дополнительном сведении и присоединять его в запросе обычным левым соединением. Второй вариант быстрее и предпочтительнее для регулярных отчётов.

Чем отличаются поля Город и НаселенныйПункт в структуре адреса?

«Город» — это населённый пункт со статусом города в иерархии адресного классификатора. «НаселенныйПункт» — сёла, деревни, посёлки и прочие пункты без статуса города. Для отображения «места» контрагента обычно берут город, а если он пуст — населённый пункт.

Как обработать адреса «Москва» и «Санкт-Петербург», где город совпадает с регионом?

Для городов федерального значения классификатор может помещать название в регион, а поле города оставлять пустым или дублировать. Надёжная логика: если город пуст, последовательно проверять НаселенныйПункт, а затем Регион с отсечением служебных слов («г», «обл», «край») — так Москва корректно попадёт в результат.

Можно ли получить город из адреса в старой конфигурации на КЛАДР?

Да. В старых версиях адрес хранится как список значений или строка с полями КЛАДР, где компоненты разделены запятыми в строгом порядке: индекс, регион, район, город, населённый пункт, улица, дом, корпус, квартира. Город — четвёртый элемент. Функция УправлениеКонтактнойИнформацией.СведенияОбАдресе() в старых БСП понимает этот формат напрямую.

Что делать, если в базе тысячи адресов введены вручную и город нужен для доставки?

Эвристический разбор даст заметный процент ошибок, что для логистики критично. Практичный путь: разово нормализовать адреса через внешний сервис подсказок адресов, сохранить структурированный результат в поле Значение, а затем включить обязательный ввод адреса через классификатор для новых контрагентов.

Итог

Что важно запомнить

Город надёжно извлекается только из структурированного адреса: в типовых конфигурациях используйте РаботаСАдресами.СведенияОбАдресе() с подстановкой НаселенныйПункт. Для адресов в свободной форме применяйте эвристический разбор с обязательной проверкой выборки, а для массовых задач — нормализацию и хранение города в отдельном реквизите.