Разработка и Конфигурация · 11 мин
Как получить город из контактной информации в 1С
Как извлечь город из контактной информации в 1С: типовые механизмы БСП, запросы к регистру, разбор значений полей, XDTO-пакет и готовые примеры кода.
Контактная информация в типовых конфигурациях 1С (УТ, ERP, Бухгалтерия, ЗУП) хранится не в виде отдельных колонок «Страна», «Город», «Улица», а в табличной части «КонтактнаяИнформация» справочников и документов. Каждая строка содержит вид контактной информации, представление (то, что видит пользователь) и служебные поля со структурированными значениями. Поэтому простой запрос «выбрать город» невозможен — значение нужно извлекать специальными механизмами.
Есть три рабочих подхода: разобрать строковое представление адреса, разобрать поле «ЗначенияПолей» (список значений или XML в зависимости от релиза БСП) либо воспользоваться готовыми функциями модуля «РаботаСАдресами» / «УправлениеКонтактнойИнформацией». Выбор зависит от версии библиотеки стандартных подсистем, от того, где нужен результат — в отчёте, запросе или коде, — и от того, насколько аккуратно пользователи заполняли адреса.
Ниже разобраны все три способа с примерами кода, ограничениями каждого и способами проверить корректность результата. Отдельно рассмотрен случай, когда город в адресе вообще не заполнен или введён вручную с ошибками.
Как устроено хранение контактной информации в типовых конфигурациях
Табличная часть «КонтактнаяИнформация» есть у справочников «Контрагенты», «Партнеры», «ФизическиеЛица», «Организации», «КонтактныеЛица» и ряда документов. Ключевые поля строки: «Тип» (Адрес, Телефон, Email и т.д.), «Вид» (ссылка на справочник «ВидыКонтактнойИнформации», например «Юридический адрес»), «Представление» (строка, которую видит пользователь) и «ЗначенияПолей».
Поле «ЗначенияПолей» — самое важное. В старых релизах БСП это строка вида «Индекс=125009, Город=Москва, …» (сериализованный список значений), в новых — XML-документ по схеме XDTO-пакета «КонтактнаяИнформация». Дополнительно существует поле «Значение» с тем же XML в более новых версиях. Именно из этих полей и извлекается город.
Важно понимать: «Представление» — это просто текст «125009, Москва, ул. Тверская, д. 1». Он формируется из структурированных полей, но может быть отредактирован вручную, поэтому парсить его запятой — ненадёжно. Структурированные поля — первичны.
Способ 1: извлечь город через модуль РаботаСАдресами
Самый корректный способ для кода на встроенном языке — функция «СведенияОбАдресе» общего модуля «РаботаСАдресами». Она принимает XML или структуру адреса и возвращает структуру с полями «Страна», «Регион», «Город», «НаселенныйПункт», «Улица» и другими. Функция сама учитывает формат хранения, поэтому код не ломается при обновлении БСП.
СтрокиАдреса = Контрагент.КонтактнаяИнформация.НайтиСтроки(
Новый Структура("Вид", Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента));
Если СтрокиАдреса.Количество() > 0 Тогда
Сведения = РаботаСАдресами.СведенияОбАдресе(СтрокиАдреса[0].Значение);
Город = Сведения.Город;
КонецЕсли;Если в вашем релизе модуль «РаботаСАдресами» отсутствует (старые конфигурации), используйте «УправлениеКонтактнойИнформацией.ПолучитьКонтактнуюИнформацияОбъекта» или разбор «ЗначенияПолей» через «УправлениеКонтактнойИнформацией.ПреобразоватьСтрокуВСписокПолей». Возвращённый список значений содержит элемент с представлением «Город», значение которого — искомая строка.
Обратите внимание: для городов федерального значения (Москва, Санкт-Петербург, Севастополь) город может быть записан в поле «Регион», а поле «Город» оказаться пустым. Проверяйте оба поля или используйте представление «НаселенныйПункт» из тех же сведений об адресе.
Способ 2: разобрать поле «ЗначенияПолей» вручную
Когда типовые модули недоступны (внешняя обработка для самописной конфигурации, консоль кода), поле разбирают напрямую. Для старого формата (список значений в строке) работает функция преобразования, для нового формата XML — чтение через XDTO или объект «ЧтениеXML» с поиском элемента, у которого локальное имя «Город».
// Старый формат: список значений в строке
СписокПолей = УправлениеКонтактнойИнформацией.ПреобразоватьСтрокуВСписокПолей(СтрокаКИ.ЗначенияПолей);
ЭлементГород = СписокПолей.НайтиПоЗначению("Город"); // поиск по представлению зависит от релиза
// Надёжнее перебрать список и сравнить Представление = "Город"
Для Каждого Эл Из СписокПолей Цикл
Если Эл.Представление = "Город" Тогда Город = Эл.Значение; КонецЕсли;
КонецЦикла;Ручной разбор оправдан только как запасной вариант. Главный риск — смена формата хранения при обновлении конфигурации: код, парсящий строку с разделителями, молча перестанет находить город. Если пишете такое решение, обязательно добавьте проверку: если город не найден ни в одном формате, фиксируйте это в журнале, а не возвращайте пустую строку без сигнала.
Способ 3: получить город в запросе и в СКД
В языке запросов нет функции разбора XML, поэтому напрямую «вытащить» город запросом нельзя. Типовая практика — выбрать в запросе ссылку на объект, представление и значения полей, а затем в цикле обхода результата вызвать «РаботаСАдресами.СведенияОбАдресе» и дополнить таблицу колонкой «Город». Для СКД это делается в событии «ПриКомпоновкеРезультата» или через набор данных «Объект» с программным заполнением.
Альтернатива для отчётов без программирования — использовать в запросе «Представление» адреса и функцию СКД «ВычислитьВыражение» с разбором строки, но это хрупкое решение: достаточно пользователю ввести адрес через «ввод в свободной форме», и логика разбора по запятым даст сбой.
Сравнение вариантов извлечения города
Самый надёжный вариант для кода; учитывает формат хранения. Ограничение: требуется БСП актуального релиза.
Подходит для старых и самописных конфигураций; ломается при смене формата хранения.
Быстро для разового отчёта; ненадёжно при ручном вводе адресов пользователями.
Стандарт для отчётов и СКД; требует программной обработки после запроса.
Как отобрать только нужный вид адреса
У одного контрагента обычно несколько адресов: юридический, фактический, почтовый. Перед извлечением города строку табличной части фильтруют по ссылке на вид контактной информации. Предопределённые элементы справочника «ВидыКонтактнойИнформации» имеют служебные имена вроде «ЮрАдресКонтрагента», «ФактАдресКонтрагента», «ПочтовыйАдресОрганизации» — точные имена смотрите в конфигураторе у конкретной конфигурации.
- 1Определите, какой вид адреса нужен: юридический, фактический или почтовый
- 2Найдите предопределённый элемент справочника «Виды контактной информации» с нужным именем
- 3Отфильтруйте табличную часть «Контактная информация» по этому виду
- 4Передайте поле «Значение» (или «ЗначенияПолей») в РаботаСАдресами.СведенияОбАдресе
- 5Прочитайте свойство «Город», при пустом значении проверьте «Регион» и «НаселенныйПункт»
- 6Проверьте результат на 2–3 контрагентах с разными форматами заполнения адреса
Если адресов с нужным видом несколько (пользователи иногда дублируют строки), берите первую строку или последнюю по дате изменения — единого правила нет, поведение нужно зафиксировать в ТЗ, иначе разные отчёты покажут разные города для одного контрагента.
Частые ошибки и ограничения
Ещё одно ограничение — адреса, введённые «в свободной форме». В этом режиме пользователь пишет произвольный текст, и структурированные поля могут быть заполнены частично или не заполнены вовсе. Единственный источник города тогда — представление, и его придётся разбирать эвристикой либо признать такие записи неразобранными и вывести в отдельный список для ручной доработки.
Как проверить результат
Как проверить результат
Город определён: «Москва» (из поля «Регион» или «Город»)
Пустая строка — значит, не обработаны города федерального значения
Запись попала в список неразобранных или город извлечён корректно
В колонке «Город» фрагмент улицы или индекс
Пустой город, ошибок в журнале регистрации нет
Исключение при вызове СведенияОбАдресе
После обновления извлечение работает без правок
Города перестали определяться — сменился формат поля «ЗначенияПолей»
Для массовой проверки удобно свернуть результат по городам и посмотреть верхние строки: типичные города вашей клиентской базы должны присутствовать, а значения вроде «д. 5» или «офис 12» — сигнал сбоя разбора. Пустые города стоит посчитать отдельно и сопоставить с количеством контрагентов без адресов — цифры должны совпадать.
Что важно запомнить
Город извлекают из структурированных полей адреса через РаботаСАдресами.СведенияОбАдресе, предварительно отобрав строку по виду контактной информации. Парсинг представления — только крайняя мера. Не забудьте про города федерального значения и адреса в свободной форме.
Частые вопросы
Можно ли получить город одним запросом без кода?
Нет, в языке запросов 1С нет функций разбора XML или списков значений. Стандартный путь — выбрать поле «Значение» в запросе и обработать его в цикле через РаботаСАдресами.СведенияОбАдресе. Для СКД используют программное заполнение набора данных.
Почему для Москвы город возвращается пустым?
Москва, Санкт-Петербург и Севастополь — города федерального значения. В структуре адреса они записываются в поле «Регион», а поле «Город» остаётся пустым. Проверяйте оба поля или используйте «НаселенныйПункт» и представление региона.
Как быть, если адрес введён в свободной форме?
Структурированные поля при свободном вводе часто пустые. Варианты: разбирать представление эвристически (ненадёжно), выводить такие записи в отдельный список для ручной доработки или попытаться сопоставить представление с классификатором адресов через типовые механизмы загрузки ФИАС/ГАР.
Чем отличаются поля «ЗначенияПолей» и «Значение»?
«ЗначенияПолей» — устаревший формат (сериализованный список значений), «Значение» — XML-документ, используемый в актуальных релизах БСП. В переходный период данные могут дублироваться в обоих полях. Читайте «Значение», а «ЗначенияПолей» используйте как запасной источник.
Как найти нужный вид контактной информации в коде?
Используйте предопределённое имя элемента справочника «ВидыКонтактнойИнформации», например Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента. Точные имена смотрите в конфигураторе. Поиск по наименованию ненадёжен — пользователь может его переименовать.
Можно ли выгрузить города всех контрагентов в Excel?
Да. Напишите обработку: запрос по табличной части «КонтактнаяИнформация» с отбором по виду адреса, обход результата с вызовом СведенияОбАдресе и вывод в табличный документ, который сохраняется в Excel. Для разовой задачи подойдёт консоль запросов с постобработкой в коде.