При работе с синхронизацией данных через формат EnterpriseData (КД3) часто возникает ситуация, когда типового состава полей XSD-пакета недостаточно. Например, нужно передать специфическую таблицу из документа «Отчет комитенту» или дополнительные расчетные данные, которых нет в стандартном формате. В этой статье мы проанализируем, как решить эту задачу, разберем предложенный пользователями «костыль» и выясним, как реализовать передачу данных штатным способом.
Рассмотрим ситуацию, когда разработчику требуется передать ТаблицуЗначений. Один из способов — это сериализация таблицы в строку и упаковка её в дополнительный реквизит объекта. Этот метод часто называют «костылем», так как он использует механизмы ПВХ (плана видов характеристик) не по прямому назначению, но он является рабочим в условиях ограниченного времени.
Проанализируем пример кода для обработки ПриОтправкеДанных в модуле менеджера обмена. Здесь данные сериализуются через ЗначениеВстрокуВнутр и записываются в программно создаваемый дополнительный реквизит:
Процедура Синхр_ПКО_Документ_ОтчетКомитенту_Отправка_ПриОтправкеДанных(ДанныеИБ, ДанныеXDTO, КомпонентыОбмена, СтекВыгрузки)
// Добавление данных в коллекцию дополнительных реквизитов XDTO-объекта
ДопРеквизиты = ДатьДополнительныеРеквизитыXDTO(ДанныеXDTO);
СтрокаДопРеквизитов = ДопРеквизиты.Добавить();
// Поиск или создание служебного дополнительного реквизита
Свойство = ДатьДопРекзитНаСервере(Неопределено, "доп_ТаблицаОтчетаКомитентуОЗакупках",
"Служебный: Таблица отчета комитенту о закупках",
Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная)));
СтрокаДопРеквизитов.Свойство = Свойство;
// Сериализация таблицы значений в системную строку 1С
СтрокаДопРеквизитов.ЗначениеСвойства = ЗначениеВСтрокуВнутр(ТЗ);
КонецПроцедуры
Разберем, что происходит в этом коде. Функция ДатьДопРеквизитНаСервере обеспечивает наличие элемента в плане видов характеристик ДополнительныеРеквизитыИСведения. Если реквизита с таким именем нет, он создается программно. Это позволяет передать строку практически неограниченной длины (благодаря КвалификаторыСтроки(0)).
Важное предостережение: использование ЗначениеВстрокуВнутр делает данные зависимыми от платформы. Кроме того, автоматическое создание элементов метаданных (ПВХ) во время обмена может привести к блокировкам базы или засорению списка доступных пользователю реквизитов в интерфейсе.
Более правильным и архитектурно чистым решением в КД3 является использование встроенного во многие объекты формата EnterpriseData свойства AdditionalInfo. Это специальный узел, предназначенный для передачи произвольной информации, которая не вошла в основной состав пакета.
Выясним преимущества этого метода:
AnyType, что позволяет передавать туда не только строки, но и структуры или другие XDTO-объекты.Посмотрим на пример того, как можно упаковать данные в AdditionalInfo на стороне отправителя:
// В обработчике ПриОтправкеДанных
Если ДанныеXDTO.Свойство("AdditionalInfo") Тогда
// Если мы хотим передать таблицу, лучше сначала преобразовать её в массив структур
МассивДанных = Новый Массив;
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
СтруктураСтроки = Новый Структура("Номенклатура, Количество, Цена",
СтрокаТЗ.Номенклатура, СтрокаТЗ.Количество, СтрокаТЗ.Цена);
МассивДанных.Добавить(СтруктураСтроки);
КонецЦикла;
// Сериализуем в JSON для универсальности
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивДанных);
СтрокаJSON = ЗаписьJSON.Закрыть();
ДанныеXDTO.AdditionalInfo = СтрокаJSON;
КонецЕсли;
На стороне приемника в обработчике ПослеЗагрузкиДанных мы сможем прочитать это значение и выполнить обратное преобразование. Рассмотрим пример получения данных:
// В обработчике ПослеЗагрузкиДанных (база-приемник)
Если ДанныеXDTO.Свойство("AdditionalInfo") И ЗначениеЗаполнено(ДанныеXDTO.AdditionalInfo) Тогда
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ДанныеXDTO.AdditionalInfo);
МассивДанных = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Далее выполняем логику обработки полученного массива структур
Для Каждого ЭлементДанных Из МассивДанных Цикл
// Например, заполняем табличную часть загруженного документа
КонецЦикла;
КонецЕсли;
Если передача специфических данных требуется регулярно и в больших объемах, проанализируем самый надежный метод — создание расширения формата. Это позволяет добавить в XDTO-пакет собственные поля и таблицы на уровне метаданных конфигурации.
Разберем этот процесс по шагам:
EnterpriseData.TableOfPurchases с необходимыми колонками).Этот путь требует глубокого знания КД3, но он гарантирует, что данные будут проверяться на соответствие схеме (валидация) еще на этапе выгрузки, что исключает ошибки чтения в базе-приемнике.
Проанализируем ситуацию и выберем оптимальный путь решения задачи:
Используйте дополнительные реквизиты (Вариант 1), если:
— Вам нужно, чтобы данные были видны пользователю в интерфейсе карточки объекта после загрузки без дополнительного программирования.
— Вам нужно быстро «пробросить» одно строковое поле без изменения логики загрузки.
Используйте AdditionalInfo (Вариант 2), если:
— Вам нужно передать техническую информацию (таблицы, ключи связи, флаги логики).
— Вы хотите избежать засорения справочников и ПВХ служебными данными.
— Вы стремитесь к универсальности (JSON-строка в AdditionalInfo — стандарт индустрии).
Используйте расширение формата (Вариант 3), если:
— Вы разрабатываете тиражное решение или крупную корпоративную систему.
— Объем передаваемых «дополнительных» данных сопоставим с объемом основных данных объекта.
— Требуется строгая типизация и контроль целостности данных.
В заключение отметим, что хотя методы с использованием ЗначениеВстрокуВнутр и кажутся простыми, они несут риски при обновлении платформы. Мы рекомендуем использовать JSON-сериализацию в сочетании с AdditionalInfo как наиболее сбалансированный и современный способ передачи произвольных данных в 1С.