В современных конфигурациях 1С, таких как Управление нашей фирмой (УНФ), контактная информация (адреса, телефоны) хранится в специальных табличных частях или регистрах сведений. Особенность заключается в том, что детальная информация об адресе (индекс, город, улица, дом) упакована в одну XML-строку (или JSON в новых версиях) в поле ЗначенияПолей. При разработке отчетов на Системе компоновки данных (СКД) программисты часто сталкиваются с тем, что просто «вытянуть» индекс запросом невозможно, а стандартные функции БСП возвращают структуру, с которой СКД не умеет работать напрямую через точку.
В этой статье мы разберем, как обойти это ограничение, правильно использовать расширения и оптимизировать получение данных из контактной информации.
Разберем ситуацию: у нас есть поле ЗначенияПолейЮрАдреса. Мы знаем, что в общем модуле есть функция РаботаСАдресами.СведенияОбАдресе(), которая парсит эту строку. Однако, если мы напишем в вычисляемом поле СКД выражение:
РаботаСАдресами.СведенияОбАдресе(ЗначенияПолейЮрАдреса).Индекс
Система выдаст ошибку. Проблема в том, что механизм вычисляемых полей СКД поддерживает вызов экспортных функций общих модулей, но он не умеет обращаться к свойствам возвращаемой структуры через точку или по индексу []. Функция возвращает объект Структура, а СКД ожидает примитивный тип (строку, число, дату). Поэтому нам необходимо создать «функцию-переходник» или «обертку».
Если ваша конфигурация находится на поддержке, лучшим способом будет использование расширения. Рассмотрим по шагам, как это реализовать:
рш_РаботаСКонтактнойИнформацией).Рассмотрим пример кода для такого модуля:
Функция ПолучитьИндексИзАдреса(ЗначенияПолей) Экспорт
Если ПустаяСтрока(ЗначенияПолей) Тогда
Возврат "";
КонецЕсли;
// Используем стандартную функцию БСП для получения структуры
СведенияОбАдресе = РаботаСАдресами.СведенияОбАдресе(ЗначенияПолей);
// Извлекаем нужное поле. В структуре БСП это обычно "Индекс"
ПочтовыйИндекс = "";
Если СведенияОбАдресе.Свойство("Индекс", ПочтовыйИндекс) Тогда
Возврат ПочтовыйИндекс;
КонецЕсли;
Возврат "";
КонецФункции
Функция ПолучитьДомИзАдреса(ЗначенияПолей) Экспорт
СведенияОбАдресе = РаботаСАдресами.СведенияОбАдресе(ЗначенияПолей);
НомерДома = "";
Если СведенияОбАдресе.Свойство("Дом", НомерДома) Тогда
Возврат НомерДома;
КонецЕсли;
Возврат "";
КонецФункции
После этого в СКД на закладке Вычисляемые поля мы можем добавить поле Индекс и в колонке Выражение написать:
рш_РаботаСКонтактнойИнформацией.ПолучитьИндексИзАдреса(ЗначенияПолейЮрАдреса)
Проанализируем ситуацию, когда функции из расширения не «подхватываются» СКД. Это частая проблема на старых версиях платформы. Для корректной работы расширений в выражениях СКД:
Если вы не хотите создавать свои функции, можно попробовать использовать более универсальные модули БСП, которые возвращают сразу строку. Проанализируем модуль УправлениеКонтактнойИнформациейКлиентСервер. В нем есть методы для разбора адресов. Однако большинство из них всё равно возвращают структуры или коллекции.
Если вам нужно просто Представление адреса, оно обычно уже есть в соседнем поле Представление таблицы контактной информации. Но для выделения конкретно номера дома или индекса без «самописной» функции-обертки в СКД обойтись крайне сложно.
Рассмотрим ситуацию, когда отчет строится по очень большому количеству контрагентов (десятки тысяч). Вызов функции из вычисляемого поля происходит построчно. Это может привести к значительным задержкам, так как для каждой строки будет выполняться парсинг XML.
В этом случае эффективнее применить другой алгоритм:
ПриКомпоновкеРезультата, выполните запрос к базе данных.ТаблицуЗначений.РаботаСАдресами.Этот метод работает значительно быстрее, так как минимизирует накладные расходы на вызов серверного контекста из движка СКД.
Выясним причину, по которой старые методы разбора строк могут «сломаться». В последних версиях БСП формат хранения в поле ЗначенияПолей может переключаться с XML на JSON. Поэтому категорически не рекомендуется использовать строковые функции типа ПОДСТРОКА или Найти прямо в запросе SQL.
Правильно использовать метод УправлениеКонтактнойИнформацией.КонтактнаяИнформацияВФорматеВнутреннегоПредставления. Он универсален: сам определяет, XML перед ним или JSON, и возвращает нормализованную структуру. Используя этот метод в своей функции-обертке, вы обеспечите стабильность отчета при обновлениях конфигурации.
Резюмируем: Для получения части адреса в СКД создайте в расширении модуль с признаком «Вызов сервера», напишите функцию, которая принимает XML-строку и возвращает строку с нужным фрагментом адреса (индексом), и вызывайте её в вычисляемых полях отчета.