Как получить почтовый индекс и номер дома из контактной информации в отчете СКД

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой IT и автоматизация бизнеса
← На главную

В современных конфигурациях 1С, таких как Управление нашей фирмой (УНФ), контактная информация (адреса, телефоны) хранится в специальных табличных частях или регистрах сведений. Особенность заключается в том, что детальная информация об адресе (индекс, город, улица, дом) упакована в одну XML-строку (или JSON в новых версиях) в поле ЗначенияПолей. При разработке отчетов на Системе компоновки данных (СКД) программисты часто сталкиваются с тем, что просто «вытянуть» индекс запросом невозможно, а стандартные функции БСП возвращают структуру, с которой СКД не умеет работать напрямую через точку.

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

Почему стандартные методы не работают в вычисляемых полях СКД

Разберем ситуацию: у нас есть поле ЗначенияПолейЮрАдреса. Мы знаем, что в общем модуле есть функция РаботаСАдресами.СведенияОбАдресе(), которая парсит эту строку. Однако, если мы напишем в вычисляемом поле СКД выражение:

РаботаСАдресами.СведенияОбАдресе(ЗначенияПолейЮрАдреса).Индекс

Система выдаст ошибку. Проблема в том, что механизм вычисляемых полей СКД поддерживает вызов экспортных функций общих модулей, но он не умеет обращаться к свойствам возвращаемой структуры через точку или по индексу []. Функция возвращает объект Структура, а СКД ожидает примитивный тип (строку, число, дату). Поэтому нам необходимо создать «функцию-переходник» или «обертку».

Решение проблемы через создание функции в расширении

Если ваша конфигурация находится на поддержке, лучшим способом будет использование расширения. Рассмотрим по шагам, как это реализовать:

  1. Создание расширения: Если у вас еще нет расширения для доработок, создайте его в конфигураторе.
  2. Добавление общего модуля: Добавьте в расширение новый общий модуль (например, рш_РаботаСКонтактнойИнформацией).
  3. Настройка модуля: В свойствах модуля обязательно должны быть установлены галочки Сервер и Вызов сервера. Если отчет будет формироваться во внешнем соединении, не забудьте соответствующий флаг.
  4. Написание функции-обертки: Нам нужна функция, которая примет XML-строку и вернет конкретное строковое значение (индекс, город или дом).

Рассмотрим пример кода для такого модуля:


Функция ПолучитьИндексИзАдреса(ЗначенияПолей) Экспорт
    
    Если ПустаяСтрока(ЗначенияПолей) Тогда
        Возврат "";
    КонецЕсли;
    
    // Используем стандартную функцию БСП для получения структуры
    СведенияОбАдресе = РаботаСАдресами.СведенияОбАдресе(ЗначенияПолей);
    
    // Извлекаем нужное поле. В структуре БСП это обычно "Индекс"
    ПочтовыйИндекс = "";
    Если СведенияОбАдресе.Свойство("Индекс", ПочтовыйИндекс) Тогда
        Возврат ПочтовыйИндекс;
    КонецЕсли;
    
    Возврат "";
    
КонецФункции

Функция ПолучитьДомИзАдреса(ЗначенияПолей) Экспорт
    
    СведенияОбАдресе = РаботаСАдресами.СведенияОбАдресе(ЗначенияПолей);
    
    НомерДома = "";
    Если СведенияОбАдресе.Свойство("Дом", НомерДома) Тогда
        Возврат НомерДома;
    КонецЕсли;
    
    Возврат "";
    
КонецФункции

После этого в СКД на закладке Вычисляемые поля мы можем добавить поле Индекс и в колонке Выражение написать:

рш_РаботаСКонтактнойИнформацией.ПолучитьИндексИзАдреса(ЗначенияПолейЮрАдреса)

Важные требования к платформе и режиму расширения

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

Использование стандартных функций БСП без расширения

Если вы не хотите создавать свои функции, можно попробовать использовать более универсальные модули БСП, которые возвращают сразу строку. Проанализируем модуль УправлениеКонтактнойИнформациейКлиентСервер. В нем есть методы для разбора адресов. Однако большинство из них всё равно возвращают структуры или коллекции.

Если вам нужно просто Представление адреса, оно обычно уже есть в соседнем поле Представление таблицы контактной информации. Но для выделения конкретно номера дома или индекса без «самописной» функции-обертки в СКД обойтись крайне сложно.

Альтернативный подход: Подготовка данных в программном коде

Рассмотрим ситуацию, когда отчет строится по очень большому количеству контрагентов (десятки тысяч). Вызов функции из вычисляемого поля происходит построчно. Это может привести к значительным задержкам, так как для каждой строки будет выполняться парсинг XML.

В этом случае эффективнее применить другой алгоритм:

  1. В схеме СКД создайте Внешний набор данных.
  2. В модуле объекта отчета, в процедуре ПриКомпоновкеРезультата, выполните запрос к базе данных.
  3. Выгрузите результат запроса в ТаблицуЗначений.
  4. Циклом пройдите по таблице и один раз программно заполните колонки «Индекс» и «Дом», используя те же функции РаботаСАдресами.
  5. Передайте готовую таблицу в процессор компоновки.

Этот метод работает значительно быстрее, так как минимизирует накладные расходы на вызов серверного контекста из движка СКД.

Нюансы формата XML и JSON

Выясним причину, по которой старые методы разбора строк могут «сломаться». В последних версиях БСП формат хранения в поле ЗначенияПолей может переключаться с XML на JSON. Поэтому категорически не рекомендуется использовать строковые функции типа ПОДСТРОКА или Найти прямо в запросе SQL.

Правильно использовать метод УправлениеКонтактнойИнформацией.КонтактнаяИнформацияВФорматеВнутреннегоПредставления. Он универсален: сам определяет, XML перед ним или JSON, и возвращает нормализованную структуру. Используя этот метод в своей функции-обертке, вы обеспечите стабильность отчета при обновлениях конфигурации.

Резюмируем: Для получения части адреса в СКД создайте в расширении модуль с признаком «Вызов сервера», напишите функцию, которая принимает XML-строку и возвращает строку с нужным фрагментом адреса (индексом), и вызывайте её в вычисляемых полях отчета.

← На главную