При разработке отчетов в 1С:Управление торговлей 11.4 (и других конфигурациях на базе БСП) часто возникает задача вывести адрес не одной строкой, а раздельно по колонкам: индекс, регион, город, улица, номер дома и квартиры. Стандартное поле Представление в контактной информации для этого не подходит, так как оно содержит неструктурированный текст. Разберем подробно, как решить эту задачу в системе компоновки данных (СКД), используя встроенные механизмы платформы и программный код.
В современных конфигурациях 1С контактная информация хранится в справочниках (например, Партнеры) в табличной части КонтактнаяИнформация. Там есть два ключевых поля:
Для корректного разбора нам необходимо работать именно с полем ЗначенияПолей. Рассмотрим три основных способа реализации этой задачи.
Проанализируем самый гибкий метод, который позволяет разбирать адрес прямо «на лету» в процессе формирования отчета. В СКД можно вызвать функцию общего модуля, передать ей структурированную строку адреса и получить нужный компонент.
Шаг 1. Создание функции в общем модуле или расширении
Поскольку нам нужно вызывать функцию из СКД, она должна быть Экспортной и находиться в модуле с установленными флагами Сервер и Вызов сервера. Если вы не хотите менять типовую конфигурацию, создайте расширение и добавьте туда новый общий модуль (например, Расш1_РаботаСАдресами).
Пример программного кода для разбора JSON-структуры адреса:
Функция ПолучитьЧастьАдреса(Значение, Часть) Экспорт
Если НЕ ЗначениеЗаполнено(Значение) Тогда
Возврат "";
КонецЕсли;
Попытка
// В новых версиях БСП адрес хранится в формате JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Значение);
Данные = ПрочитатьJSON(ЧтениеJSON, Ложь);
ЧтениеJSON.Закрыть();
Если Часть = "Индекс" Тогда
Возврат Данные.ZIPcode;
ИначеЕсли Часть = "Регион" Тогда
Возврат Данные.area;
ИначеЕсли Часть = "Город" Тогда
// Проверяем город или населенный пункт
Возврат ?(ЗначениеЗаполнено(Данные.city), Данные.city, Данные.locality);
ИначеЕсли Часть = "Улица" Тогда
Возврат Данные.street;
ИначеЕсли Часть = "Дом" Тогда
Возврат Данные.houseNumber;
КонецЕсли;
Исключение
// Если формат не JSON (например, старый XML), используем стандартные методы БСП
Сведения = РаботаСАдресами.СведенияОбАдресе(Значение);
Если Часть = "Индекс" Тогда Возврат Сведения.Индекс;
ИначеЕсли Часть = "Регион" Тогда Возврат Сведения.Регион;
ИначеЕсли Часть = "Город" Тогда Возврат Сведения.Город;
ИначеЕсли Часть = "Улица" Тогда Возврат Сведения.Улица;
ИначеЕсли Часть = "Дом" Тогда Возврат Сведения.Дом;
КонецЕсли;
КонецПопытки;
Возврат "";
КонецФункции
Шаг 2. Настройка СКД
Рассмотрим порядок действий в конструкторе схемы компоновки данных:
ЗначенияПолей из таблицы контактной информации партнеров.Город).Расш1_РаботаСАдресами.ПолучитьЧастьАдреса(ЗначенияПолей, "Город").Выясним, как упростить задачу, если в вашей конфигурации уже есть мощные механизмы Библиотеки стандартных подсистем (БСП). Вместо написания своего парсера JSON, в выражении вычисляемого поля СКД можно попробовать вызвать типовые функции.
Посмотрим на примеры функций, которые часто доступны в общем модуле РаботаСАдресами или КонтактнаяИнформацияСлужебный:
РаботаСАдресами.СведенияОбАдресе(ЗначенияПолей).ГородРаботаСАдресами.СведенияОбАдресе(ЗначенияПолей).УлицаВажный нюанс: Стандартная функция СведенияОбАдресе возвращает структуру. Платформа 1С в СКД позволяет обращаться к свойствам структур через точку, но это может работать не во всех версиях или требовать предварительной проверки на NULL.
Проанализируем ситуацию, когда отчет формируется по очень большому количеству контрагентов (десятки тысяч строк). Вызов функции модуля для каждой строки в вычисляемых полях может существенно замедлить формирование отчета (проблема N+1).
В этом случае эффективнее использовать следующий алгоритм:
ТаблицуЗначений.КонтактнаяИнформацияСлужебный.СформироватьПредставленияСлужебный(). Это гораздо быстрее, чем парсить каждую строку отдельно.ТаблицуЗначений в СКД как Набор данных - объект.Разберем основные трудности, с которыми сталкиваются разработчики:
РаботаСАдресами.СведенияОбАдресе просто текст адреса, функция не сможет его разобрать на составляющие, так как в тексте нет четких разделителей для типов объектов (где заканчивается город и начинается район). Всегда используйте XML/JSON из поля ЗначенияПолей.addressType в JSON. Если тип муниципальный, город может находиться в поле settlement (поселение) или municipalDistrict.country и текстовое поле адреса. Проверьте это в коде функции, чтобы избежать ошибок Значение не является значением объектного типа.Таким образом, самым надежным способом является сочетание использования вычисляемых полей СКД и экспортной функции, которая умеет обрабатывать как современный JSON-формат, так и старый XML, опираясь на стандартные возможности БСП.