Как передать доступные поля выбора СКД в JSON для внешнего конструктора

Программист IT и автоматизация бизнеса
← На главную

Передача метаданных Системы Компоновки Данных (СКД) во внешние сервисы — это сложная техническая задача. Основная проблема заключается в том, что объект ДоступныеПоляКомпоновкиДанных не является простым объектом данных, который можно сериализовать одной командой. Разберем подробно, как реализовать передачу структуры полей в формате JSON для создания внешнего конструктора отчетов, используя в том числе наработки по выгрузке метаданных в JSON.

Проблема прямой сериализации и пути её решения

Если мы попытаемся использовать стандартную функцию ЗаписатьJSON непосредственно для объекта КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора, мы столкнемся с тем, что система либо выдаст ошибку, либо вернет пустой объект. Это происходит потому, что коллекции СКД являются специализированными объектами платформы, не поддерживающими автоматическую XDTO-сериализацию в JSON «из коробки».

Проанализируем основные стратегии, которые мы можем применить для решения этой задачи:

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

Метод 1: Рекурсивный обход доступных полей

Рассмотрим наиболее гибкий способ — ручной перебор полей. Доступные поля в СКД организованы иерархически: например, поле «Номенклатура» может содержать вложенные поля «Код», «Артикул», «Родитель» и так далее. Нам необходимо создать функцию, которая пройдет по всему дереву. Для удобного формирования таких вложенных структур можно использовать генератор объектов (массивы+структуры) для JSON, работающий в стиле Fluent.

Выясним, какие свойства каждого поля нам критически важны для передачи во внешний сервис:

Пример кода для обхода коллекции полей может выглядеть следующим образом:


Функция ПолучитьДеревоДоступныхПолей(КоллекцияПолей)
    Результат = Новый Массив;
    
    Для Каждого Поле Из КоллекцияПолей Цикл
        СтруктураПоля = Новый Структура;
        СтруктураПоля.Вставить("Имя", Поле.Поле);
        СтруктураПоля.Вставить("Заголовок", Поле.Заголовок);
        СтруктураПоля.Вставить("ЭтоГруппа", Поле.Поля.Количество() > 0);
        
        // Рекурсивно обрабатываем вложенные поля
        Если Поле.Поля.Количество() > 0 Тогда
            СтруктураПоля.Вставить("ВложенныеПоля", ПолучитьДеревоДоступныхПолей(Поле.Поля));
        КонецЕсли;
        
        Результат.Добавить(СтруктураПоля);
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Посмотрим на важный нюанс: при большой вложенности (например, в типовых конфигурациях ERP или УХ) дерево полей может быть огромным. В таких случаях мы рекомендуем использовать «ленивую загрузку» (lazy load).

Метод 2: Промежуточная XML-сериализация

Проанализируем ситуацию, когда нам нужно передать настройки максимально быстро без написания сложной логики обхода. Объект КомпоновщикНастроек и сама схема СКД поддерживают методы ЗаписатьXML. Мы можем сохранить объект в XML-строку, а затем преобразовать этот XML в JSON на стороне 1С или на стороне внешнего сервиса.

Рассмотрим пример сохранения настроек в строку XML:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, КомпоновщикНастроек.Настройки);
XMLСтрока = ЗаписьXML.Закрыть();
// Далее XMLСтрока может быть конвертирована в JSON стандартными методами

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

Обработка типов данных и ссылок

Выясним, как передавать типы данных. В СКД свойство ТипЗначения имеет тип ОписаниеТипов. Чтобы внешний сервис «понимал», что перед ним — число, дата или ссылка на справочник «Контрагенты», нам нужно преобразовать ОписаниеТипов в массив строк.

Для ссылочных типов данных (справочники, документы) во внешнем сервисе обычно потребуется реализовать API-метод. В JSON мы передаем метаданные о типе, например: "type": "Catalog.Ref.Counterparties". При программной обработке состава полей полезно иметь под рукой СКДБилдер: модуль-обёртку над объектной моделью СКД, который значительно упрощает код.

Важный момент при работе с отборами: если вы передаете уже установленные отборы, помните, что значения ссылок в 1С (UUID) должны быть понятны внешнему сервису. Используйте метод ЗначениеВСтрокуВнутр или просто передавайте GUID ссылки.

Получение настроек обратно в 1С

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

  1. Десериализуем JSON в структуру 1С с помощью ЧтениеJSON.
  2. На данном этапе крайне важна проверка на заполненность обязательных полей в строке JSON, чтобы гарантировать целостность загружаемых настроек.
  3. Очищаем текущие выбранные поля в КомпоновщикНастроек.Настройки.Выбор.
  4. Циклом обходим массив из JSON и добавляем новые элементы типа ВыбранноеПолеКомпоновкиДанных.
  5. Для каждого поля устанавливаем свойство Поле, создавая новый объект ПолеКомпоновкиДанных(ИмяПоляИзJSON).

Использование ФабрикаXDTO.ПрочитатьJSON может быть полезным, если вы предварительно создали XDTO-пакет, описывающий структуру вашего JSON. Это позволит автоматически типизировать данные при чтении, что значительно упростит код загрузки настроек.

Заключение

Реализация внешнего конструктора СКД — задача трудоемкая, требующая понимания внутренней структуры метаданных 1С. Мы рекомендуем комбинировать подходы: использовать рекурсивный обход для построения дерева доступных полей и стандартную XDTO-сериализацию для передачи самих настроек (отборов и параметров). Это обеспечит баланс между удобством использования на стороне веб-сервиса и надежностью работы в 1С.

← На главную