Как передать массив или сложную структуру через AdditionalInfo в Конвертации данных 3.0?

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

При работе с технологией Конвертация данных 3.0 и форматом Enterprise Data разработчики часто сталкиваются с необходимостью передать дополнительные сведения, которые не предусмотрены стандартным составом свойств XDTO-пакета. Для этих целей в формате существует свойство AdditionalInfo. Однако попытка передать в него массив или вложенную структуру часто приводит к ошибкам платформы. В этой статье мы разберем, почему это происходит, и проанализируем наиболее эффективные способы решения данной задачи. Для базового знакомства с архитектурой обмена подойдёт руководство по Конвертации данных 3.0 и формату Enterprise Data.

Почему возникает ошибка при передаче массива

Разберем ситуацию на примере. Предположим, мы пытаемся передать массив ссылок на упаковки номенклатуры, предварительно преобразовав их в объекты XDTO. Рассмотрим типичный код, который вызывает затруднения:


ДополнительныеДанные = Новый Структура;
МассивУпаковок = Новый Массив;   

ПКО_Упаковки = ОбменДаннымиXDTOСервер.ПКОПоИмени(КомпонентыОбмена, "Справочник_Упаковки");

Пока Выборка.Следующий() Цикл
    // Превращаем ссылку ИБ в объект XDTO по правилам конвертации
    ДанныеПоПравилам = ОбменДаннымиXDTOСервер.ДанныеXDTOИзДанныхИБ(КомпонентыОбмена, Выборка.Ссылка, ПКО_Упаковки); 
    МассивУпаковок.Добавить(ДанныеПоПравилам);
КонецЦикла;	

ДополнительныеДанные.Вставить("УпаковкиНоменклатуры", МассивУпаковок);
ДанныеXDTO.Вставить("AdditionalInfo", ДополнительныеДанные);

Проблема заключается в том, что свойство AdditionalInfo в схеме Enterprise Data обычно описывается типом v8:Structure. Этот тип в реализации 1С ожидает набор пар «Ключ-Значение», где значением должен выступать примитивный тип (строка, число, дата, булево). Когда мы пытаемся поместить туда Массив, содержащий ОбъектXDTO, механизм сериализации не находит описания этого вложенного типа внутри структуры и выдает ошибку. Система просто «не знает», как упаковать сложный объект в XML-поле, предназначенное для простых данных.

Решение 1: Сериализация коллекции в строку JSON

Проанализируем самый современный и надежный способ — использование формата JSON. Поскольку в AdditionalInfo мы гарантированно можем передать строку, мы можем «упаковать» наш массив в компактную JSON-строку на стороне источника и «распаковать» ее на стороне приемника. Это позволяет сохранить структуру данных любой вложенности.

Рассмотрим, как изменить код формирования данных:


// Формируем массив простых данных (например, структур с кодами или артикулами)
МассивДляПередачи = Новый Массив;
Пока Выборка.Следующий() Цикл
    ИнфоОбУпаковке = Новый Структура("Код, Наименование", Выборка.Код, Выборка.Наименование);
    МассивДляПередачи.Добавить(ИнфоОбУпаковке);
КонецЦикла;

// Сериализуем массив в JSON-строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивДляПередачи);
СтрокаJSON = ЗаписьJSON.Закрыть();

// Помещаем строку в AdditionalInfo
ДополнительныеДанные = Новый Структура;
ДополнительныеДанные.Вставить("УпаковкиНоменклатурыJSON", СтрокаJSON);
ДанныеXDTO.Вставить("AdditionalInfo", ДополнительныеДанные);

Важный нюанс: В данном примере мы передаем не объекты XDTO, а простые структуры. Если вам необходимо передать именно результат работы ДанныеXDTOИзДанныхИБ, помните, что объекты XDTO напрямую не сериализуются через ЗаписатьJSON. В этом случае лучше передать ключевые реквизиты (УИД, Код) и найти/создать объекты уже на стороне приемника.

Решение 2: Использование СериализатораXDTO

Если нам необходимо передать данные в формате XML внутри свойства, мы можем воспользоваться встроенным объектом СериализаторXDTO. Этот метод позволяет преобразовать любой объект 1С (включая массивы и структуры) в строку XML, которую понимает платформа.

Выясним, как реализовать этот подход:


// На стороне источника
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, МассивУпаковок);
СтрокаXML = ЗаписьXML.Закрыть();

ДополнительныеДанные = Новый Структура;
ДополнительныеДанные.Вставить("ДанныеВФорматеXML", СтрокаXML);
ДанныеXDTO.Вставить("AdditionalInfo", ДополнительныеДанные);

На стороне приемника в обработчике ПослеЗагрузки или ПередЗаписью вам потребуется выполнить обратную операцию с помощью метода СериализаторXDTO.ПрочитатьXML().

Решение 3: Передача через разделители (для простых списков)

Если массив состоит из простых строк (например, только артикулы или коды), использование JSON или XML может быть избыточным. В таких ситуациях мы можем применить простую конкатенацию строк с разделителем.

Посмотрим на пример:


СписокКодов = "";
Для Каждого Элемент Из МассивКодов Цикл
    СписокКодов = СписокКодов + Элемент + ";";
КонецЦикла;

ДополнительныеДанные = Новый Структура;
ДополнительныеДанные.Вставить("СписокКодов", СписокКодов);
ДанныеXDTO.Вставить("AdditionalInfo", ДополнительныеДанные);

На приемнике такая строка легко превращается обратно в массив с помощью функции СтрРазделить(Строка, ";").

Как обрабатывать полученные данные на приемнике

Важно понимать, что при использовании любого из вышеперечисленных методов автоматического «развертывания» данных в объекты 1С не произойдет. Вам необходимо программно обработать содержимое AdditionalInfo в правилах конвертации объектов (ПКО). Для настройки соответствий объектов между базами можно использовать подход к формированию мэппинга в формате EnterpriseData.

Разберем алгоритм действий в обработчике ПослеЗагрузки:

  1. Проверить наличие нужного ключа в структуре ДополнительныеДанные.
  2. Если используется JSON — вызвать ЧтениеJSON и ПрочитатьJSON.
  3. Если используется XML-сериализация — вызвать СериализаторXDTO.ПрочитатьXML.
  4. На основе полученного массива выполнить поиск ссылок в базе данных или создать новые записи.

Рекомендации

Подводя итог, можно выделить следующие правила работы с AdditionalInfo в КД 3.0:

Таким образом, использование строковой сериализации (особенно JSON) является стандартным и общепринятым «обходным путем» в сообществе разработчиков 1С при работе с Конвертацией данных 3.0.

← На главную