Передача метаданных Системы Компоновки Данных (СКД) во внешние сервисы — это сложная техническая задача. Основная проблема заключается в том, что объект ДоступныеПоляКомпоновкиДанных не является простым объектом данных, который можно сериализовать одной командой. Разберем подробно, как реализовать передачу структуры полей в формате JSON для создания внешнего конструктора отчетов, используя в том числе наработки по выгрузке метаданных в JSON.
Если мы попытаемся использовать стандартную функцию ЗаписатьJSON непосредственно для объекта КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора, мы столкнемся с тем, что система либо выдаст ошибку, либо вернет пустой объект. Это происходит потому, что коллекции СКД являются специализированными объектами платформы, не поддерживающими автоматическую XDTO-сериализацию в JSON «из коробки».
Проанализируем основные стратегии, которые мы можем применить для решения этой задачи:
Рассмотрим наиболее гибкий способ — ручной перебор полей. Доступные поля в СКД организованы иерархически: например, поле «Номенклатура» может содержать вложенные поля «Код», «Артикул», «Родитель» и так далее. Нам необходимо создать функцию, которая пройдет по всему дереву. Для удобного формирования таких вложенных структур можно использовать генератор объектов (массивы+структуры) для JSON, работающий в стиле Fluent.
Выясним, какие свойства каждого поля нам критически важны для передачи во внешний сервис:
Имя: технический путь к данным (например, "Номенклатура.Код").Заголовок: понятное пользователю название.ТипЗначения: описание типов для корректного отображения элементов управления в веб-инветрфейсе.ДоступноДляВыбора, ДоступноДляГруппировки, ДоступноДляОтбора.Пример кода для обхода коллекции полей может выглядеть следующим образом:
Функция ПолучитьДеревоДоступныхПолей(КоллекцияПолей)
Результат = Новый Массив;
Для Каждого Поле Из КоллекцияПолей Цикл
СтруктураПоля = Новый Структура;
СтруктураПоля.Вставить("Имя", Поле.Поле);
СтруктураПоля.Вставить("Заголовок", Поле.Заголовок);
СтруктураПоля.Вставить("ЭтоГруппа", Поле.Поля.Количество() > 0);
// Рекурсивно обрабатываем вложенные поля
Если Поле.Поля.Количество() > 0 Тогда
СтруктураПоля.Вставить("ВложенныеПоля", ПолучитьДеревоДоступныхПолей(Поле.Поля));
КонецЕсли;
Результат.Добавить(СтруктураПоля);
КонецЦикла;
Возврат Результат;
КонецФункции
Посмотрим на важный нюанс: при большой вложенности (например, в типовых конфигурациях ERP или УХ) дерево полей может быть огромным. В таких случаях мы рекомендуем использовать «ленивую загрузку» (lazy load).
Проанализируем ситуацию, когда нам нужно передать настройки максимально быстро без написания сложной логики обхода. Объект КомпоновщикНастроек и сама схема СКД поддерживают методы Записать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 ссылки.
После того как пользователь во внешнем сервисе сформировал JSON с выбранными полями и отборами, нам нужно загрузить его обратно. Разберем по шагам этот процесс:
ЧтениеJSON.КомпоновщикНастроек.Настройки.Выбор.ВыбранноеПолеКомпоновкиДанных.Поле, создавая новый объект ПолеКомпоновкиДанных(ИмяПоляИзJSON).Использование ФабрикаXDTO.ПрочитатьJSON может быть полезным, если вы предварительно создали XDTO-пакет, описывающий структуру вашего JSON. Это позволит автоматически типизировать данные при чтении, что значительно упростит код загрузки настроек.
Реализация внешнего конструктора СКД — задача трудоемкая, требующая понимания внутренней структуры метаданных 1С. Мы рекомендуем комбинировать подходы: использовать рекурсивный обход для построения дерева доступных полей и стандартную XDTO-сериализацию для передачи самих настроек (отборов и параметров). Это обеспечит баланс между удобством использования на стороне веб-сервиса и надежностью работы в 1С.