Разработка и Конфигурация · 12 мин
Как в 1С получить город из адреса
Как в 1С получить город из адреса: работа с ФИАС/КЛАДР, функция РаботаСАдресами, разбор строки адреса, контактная информация и проверка результата.
Задача получить город из адреса возникает в 1С постоянно: при формировании отчётов по регионам, расчёте стоимости доставки, маршрутизации документов и выгрузке данных во внешние системы. Сложность в том, что адрес в 1С может храниться в разных форматах — как единая строка «в свободной форме», как структурированные данные по ФИАС или КЛАДР, а также как набор полей в табличной части контактной информации.
Универсального решения «на одну кнопку» не существует: способ извлечения города зависит от того, как именно адрес попал в базу. Если контрагенты вводились аккуратно через адресный классификатор — город легко получить штатными средствами БСП (библиотеки стандартных подсистем). Если адрес вводили вручную строкой, придётся разбирать её программно, и результат будет требовать проверки.
Ниже разобраны рабочие подходы: штатная функция РаботаСАдресами.СведенияОбАдресе(), разбор JSON-представления контактной информации, парсинг произвольной строки и типовые ошибки, которые приводят к пустому или неверному городу.
Как 1С хранит адрес и почему это важно
В типовых конфигурациях (УТ, ERP, Бухгалтерия, ЗУП) адрес хранится в регистре сведений «Контактная информация» в двух видах одновременно: поле Представление — это строка для показа пользователю, а поле Значение (в новых версиях) — JSON-структура с разложенными по полям компонентами адреса. В старых базах вместо JSON используется список значений с полями КЛАДР.
Ключевой момент: если адрес вводился через адресный классификатор (кнопка выбора из ФИАС), JSON содержит отдельные элементы — регион, район, город, населённый пункт, улица, дом. Тогда город извлекается по имени поля без всякого разбора строки. Если же пользователь просто напечатал адрес в поле представления, JSON может быть пустым или содержать только строку целиком.
Поэтому первый шаг любого решения — определить, какая доля адресов в базе структурирована. Это можно сделать запросом: выбрать записи контактной информации с видом «Адрес» и проверить, заполнено ли поле Значение и есть ли в нём элемент с типом «Город».
Способ 1. Штатная функция РаботаСАдресами.СведенияОбАдресе()
В конфигурациях на базе БСП есть модуль РаботаСАдресами (в старых версиях — УправлениеКонтактнойИнформацией). Функция СведенияОбАдресе() принимает адрес в виде строки JSON или списка значений и возвращает структуру с полями: Индекс, Регион, Район, Город, НаселенныйПункт, Улица, Дом, Корпус, Квартира и другие.
Типовой код выглядит так: сначала получаем значение контактной информации объекта, затем передаём его в функцию и читаем нужное поле.
КИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
КонтрагентСсылка,
Перечисления.ТипыКонтактнойИнформации.Адрес);
Для Каждого СтрокаКИ Из КИ Цикл
Сведения = РаботаСАдресами.СведенияОбАдресе(СтрокаКИ.Значение);
Город = Сведения.Город;
Если ПустаяСтрока(Город) Тогда
Город = Сведения.НаселенныйПункт;
КонецЕсли;
КонецЦикла;
Обратите внимание на подстановку НаселенныйПункт: для адресов в сельской местности поле «Город» пусто, а населённый пункт хранится отдельно. Для городов федерального значения (Москва, Санкт-Петербург, Севастополь) город может совпадать с регионом или находиться в поле НаселенныйПункт — зависит от версии классификатора.
Сведения = РаботаСАдресами.СведенияОбАдресе(СтрокаКИ.Значение);
Город = ?(ПустаяСтрока(Сведения.Город), Сведения.НаселенныйПункт, Сведения.Город);Способ 2. Разбор JSON контактной информации вручную
Если по какой-то причине функция БСП недоступна (самописная конфигурация, обрезанная библиотека), JSON можно разобрать напрямую штатным объектом ЧтениеJSON. В структуре адреса город находится в массиве value → элементы area (район), city (город), settlement (населённый пункт) — точные имена зависят от формата, поэтому надёжнее искать по типу элемента.
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
Данные = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
Город = "";
Если Данные.Получить("city") <> Неопределено Тогда
Город = Данные["city"];
ИначеЕсли Данные.Получить("settlement") <> Неопределено Тогда
Город = Данные["settlement"];
КонецЕсли;
Структура JSON отличается между версиями БСП и форматами (ФИАС, ГАР), поэтому перед промышленным использованием выгрузите несколько реальных адресов из своей базы и посмотрите фактические имена ключей. Полагаться на документацию одной версии при работе с другой — частая причина пустого результата.
Способ 3. Разбор адреса, введённого свободной строкой
Когда адрес хранится только как строка вида «г. Екатеринбург, ул. Ленина, д. 5», структурированных полей нет и приходится разбирать текст. Простейший подход — разделить строку по запятым и искать фрагмент с маркерами «г.», «г », «город», «пгт», «с.», «д.» (деревня) и т.п.
Части = СтрРазделить(ПредставлениеАдреса, ",");
Город = "";
Для Каждого Часть Из Части Цикл
Тест = НРег(СокрЛП(Часть));
Если СтрНачинаетсяС(Тест, "г.") Или СтрНачинаетсяС(Тест, "г ") Тогда
Город = СокрЛП(Часть);
Прервать;
КонецЕсли;
КонецЦикла;
Этот метод эвристический: он ошибается, когда в адресе нет префикса «г.» (просто «Екатеринбург, ул. Ленина»), когда город и регион слиты («Москва, ул. Тверская» — здесь город совпадает с регионом), или когда районный центр указан раньше города. Для массовой обработки такие адреса лучше прогнать через сервис нормализации (например, через API подсказок адресов) и сохранить результат обратно в структурированном виде.
Как выбрать подход под свою ситуацию
Выбор способа определяется двумя факторами: форматом хранения адресов и масштабом задачи. Разовое получение города в отчёте и массовая миграция базы — разные сценарии с разными требованиями к надёжности.
Сравнение способов получения города
Подходит для типовых конфигураций с адресами, введёнными через классификатор. Точный результат, но требует заполненного поля Значение.
Для самописных конфигураций и нестандартных интеграций. Требует знания фактической структуры JSON в вашей базе.
Единственный вариант для адресов в свободной форме. Эвристика: даёт ошибки на нестандартных записях, требует проверки.
Для массовой очистки legacy-данных. Даёт структурированный адрес из любой строки, но требует доступа в интернет и согласования передачи персональных данных.
Для отчётов «на лету» достаточно функции БСП с подстановкой населённого пункта. Для миграции старой базы с адресами строкой разумнее один раз нормализовать данные через сервис и дальше работать только со структурой — это снимет проблему навсегда.
Как выбрать действие
Проверка результата и типичные ошибки
После внедрения любого из способов результат нужно проверить на реальных данных. Возьмите выборку из 20–30 контрагентов из разных регионов, включая города федерального значения, сельские адреса и адреса с районными центрами, и сравните извлечённый город с ожидаемым.
Как проверить результат
Возвращается «Москва»
Пустая строка или «Москва г» дублируется с регионом
Возвращается «Иваново» из поля НаселенныйПункт
Пустой город, потому что читается только поле Город
Город извлечён, район не подставлен вместо города
В город попал район или регион
Город определён или запись помечена для ручной проверки
В город попала улица или индекс
Наиболее частые ошибки при самостоятельной реализации:
Массовая обработка и производительность
Если город нужен в отчёте по тысячам контрагентов, не вызывайте разбор адреса в цикле по строкам отчёта — это заметно замедлит формирование. Правильнее один раз собрать соответствие «Контрагент → Город» в соответствие (map) или временную таблицу и дальше использовать её.
Для регулярных отчётов по регионам и городам оправдано хранить извлечённый город в дополнительном сведении контрагента и обновлять его регламентным заданием или подпиской на запись контактной информации. Тогда отчёты работают с готовым полем без разбора JSON при каждом формировании.
- 1Проверьте запросом, какая доля адресов имеет заполненное поле Значение (JSON).
- 2Для структурированных адресов используйте РаботаСАдресами.СведенияОбАдресе() с подстановкой НаселенныйПункт.
- 3Для адресов строкой добавьте эвристический разбор с пометкой сомнительных записей.
- 4Проверьте результат на выборке из разных регионов и типов населённых пунктов.
- 5Вынесите город в дополнительное сведение и обновляйте его подпиской или регламентным заданием.
Перед написанием собственного разбора JSON выгрузите через консоль кода три-четыре реальных значения из регистра КонтактнаяИнформация и посмотрите фактические имена ключей. В разных версиях БСП и форматах ФИАС/ГАР они отличаются, и код, написанный «по документации», нередко возвращает пустые поля.
Часто задаваемые вопросы
Почему СведенияОбАдресе() возвращает пустой город, хотя адрес заполнен?
Чаще всего адрес введён вручную строкой, и поле Значение (JSON) не содержит разложенных компонентов — разбирать нечего. Вторая причина: это сельский адрес, где населённый пункт хранится в поле «НаселенныйПункт», а «Город» пуст по определению. Проверьте оба поля и содержимое JSON.
Как получить город в запросе, не используя код?
Штатно в языке запросов разобрать JSON нельзя. Варианты: использовать СКД с вычисляемым полем и функцией из общего модуля, либо хранить город в отдельном дополнительном сведении и присоединять его в запросе обычным левым соединением. Второй вариант быстрее и предпочтительнее для регулярных отчётов.
Чем отличаются поля Город и НаселенныйПункт в структуре адреса?
«Город» — это населённый пункт со статусом города в иерархии адресного классификатора. «НаселенныйПункт» — сёла, деревни, посёлки и прочие пункты без статуса города. Для отображения «места» контрагента обычно берут город, а если он пуст — населённый пункт.
Как обработать адреса «Москва» и «Санкт-Петербург», где город совпадает с регионом?
Для городов федерального значения классификатор может помещать название в регион, а поле города оставлять пустым или дублировать. Надёжная логика: если город пуст, последовательно проверять НаселенныйПункт, а затем Регион с отсечением служебных слов («г», «обл», «край») — так Москва корректно попадёт в результат.
Можно ли получить город из адреса в старой конфигурации на КЛАДР?
Да. В старых версиях адрес хранится как список значений или строка с полями КЛАДР, где компоненты разделены запятыми в строгом порядке: индекс, регион, район, город, населённый пункт, улица, дом, корпус, квартира. Город — четвёртый элемент. Функция УправлениеКонтактнойИнформацией.СведенияОбАдресе() в старых БСП понимает этот формат напрямую.
Что делать, если в базе тысячи адресов введены вручную и город нужен для доставки?
Эвристический разбор даст заметный процент ошибок, что для логистики критично. Практичный путь: разово нормализовать адреса через внешний сервис подсказок адресов, сохранить структурированный результат в поле Значение, а затем включить обязательный ввод адреса через классификатор для новых контрагентов.
Что важно запомнить
Город надёжно извлекается только из структурированного адреса: в типовых конфигурациях используйте РаботаСАдресами.СведенияОбАдресе() с подстановкой НаселенныйПункт. Для адресов в свободной форме применяйте эвристический разбор с обязательной проверкой выборки, а для массовых задач — нормализацию и хранение города в отдельном реквизите.