Рассмотрим частую и довольно нетривиальную задачу при настройке обменов через «1С:Конвертация данных 2.1» (КД 2.1). Допустим, в базе-источнике есть документ с табличной частью (ТЧ), которой физически нет в документе-получателе. Тем не менее, нам необходимо выгрузить эти данные, передать их в базу-приемник и определенным образом обработать при загрузке — например, создать на основании этих строк совершенно другой документ.
При прямолинейной настройке мы часто сталкиваемся с ошибками вида «Ошибка получения значения свойства объекта (по имени свойства источника)» или «Поле объекта не обнаружено» — для поиска расхождений и контроля переноса пригодится инструмент сравнения данных между любыми базами 1С. Проанализируем ситуацию по шагам и разберем несколько надежных способов реализации этой задачи.
Разберем базовый механизм, который позволяет взять всю табличную часть и положить её в один параметр, чтобы на стороне приемника мы могли работать с ней как с коллекцией строк.
Чтобы избежать ошибки «Поле объекта не обнаружено» (когда система пытается прочитать реквизит приемника, которого нет), нам необходимо программно определить, что именно мы передаем. Зайдем в обработчик события «Перед выгрузкой» для созданного ПКС и напишем следующий код:
// Выгружаем табличную часть источника в таблицу значений
Значение = Источник.Товары.Выгрузить();
Таким образом, мы явно говорим КД 2.1, что в данный параметр должна поместиться сформированная таблица значений. При выгрузке эта коллекция будет сериализована в XML и благополучно долетит до базы-приемника.
Проанализируем сопутствующую проблему. Иногда разработчики пытаются настроить Правило выгрузки группы свойств (ПВГС) для ТЧ и указывают приемник. В таком случае данные выгружаются, но в документе-получателе 1С автоматически создает столько же пустых строк, сколько было в источнике. Это происходит потому, что КД 2.1 отрабатывает алгоритм: раз есть группа свойств для ТЧ, нужно создать строки.
Чтобы предотвратить это поведение, нам необходимо вмешаться в процесс выгрузки группы свойств. Откроем ПВГС нашей табличной части и в событии «Перед выгрузкой» напишем всего одну строку кода:
Отказ = Истина;
Посмотрим на результат: система отменит стандартную генерацию строк для табличной части приемника, но при этом все вложенные параметры (настроенные в ПКС внутри этой группы с флагом «Передавать в параметр») все равно будут корректно выгружены в узел XML. Документ останется чистым, а данные будут ждать нас в параметрах.
Если задача заключается в том, чтобы на основе разных табличных частей одного документа создать разные документы в базе-приемнике, стандартное поведение КД 2.1 может мешать. По умолчанию, на один объект срабатывает только одно Правило выгрузки данных (ПВД). Второе ПВД для того же объекта будет проигнорировано.
Разберем, как обойти это ограничение. Мы можем инициировать выгрузку связанных или новых объектов программно с помощью функции ВыгрузитьПоПравилу(). Посмотрим на пример, где мы подготавливаем структуру с данными и передаем её в другое ПКО.
В ПВД исходного документа (например, в событии «Перед выгрузкой») напишем:
// Подготавливаем таблицу товаров
ТаблицаТоваров = Источник.Товары.Выгрузить();
// Формируем структуру входящих данных для целевого ПКО
ПараметрыВызова = Новый Структура;
ПараметрыВызова.Вставить("Товары", ТаблицаТоваров);
ПараметрыВызова.Вставить("ДополнительныйРеквизит", Источник.Контрагент);
// Вызываем выгрузку по нужному правилу программно
ВыгрузитьПоПравилу(, , , ПараметрыВызова, "ОтчетОРозничныхПродажахВОплатуСтраховыми");
Теперь перейдем в то ПКО, которое мы вызвали (ОтчетОРозничныхПродажахВОплатуСтраховыми). Чтобы оно поняло, откуда брать данные, в правилах конвертации свойств (ПКС) необходимо установить флаг «Получать из входящих данных». А в обработчике ПКС (Перед выгрузкой) можно напрямую обратиться к переданной структуре:
КоллекцияОбъектов = ВходящиеДанные.Товары;
Рассмотрим подводный камень программной выгрузки. Если вы используете ВыгрузитьПоПравилу() в событии «После выгрузки» основного объекта, вы можете обнаружить, что связанный документ создается, но его табличная часть пустая. Причем в файле обмена данные могут даже присутствовать.
Выясним причину: событие «После выгрузки» срабатывает, когда основной объект сформирован в памяти, но запись узла в XML еще не завершена окончательно. Вложенные вызовы других правил могут нарушить контекст выгрузки.
Для гарантированной и корректной выгрузки связанных документов с табличными частями используйте событие «После выгрузки в файл». В этот момент текущий объект уже полностью записан в поток XML, и инициализация нового узла через ВыгрузитьПоПравилу() пройдет изолированно и безопасно.
Завершим наш процесс настройкой базы-получателя. Когда данные выгружены через параметры (как мы сделали в Способе 1), при загрузке они помещаются во временное хранилище (для этого пригодится универсальная обработка выгрузки и загрузки данных с обработчиками).
Откроем ПКО документа-приемника и перейдем в событие «После загрузки». Обратимся к коллекции ПараметрыОбъекта. Важно помнить, что при обмене между разными конфигурациями таблица значений может сериализоваться в массив структур. Напишем универсальный код обработки:
Если ПараметрыОбъекта <> Неопределено Тогда
ПереданныеТовары = ПараметрыОбъекта["Товары"];
Если ПереданныеТовары <> Неопределено Тогда
// Создаем новый документ на основе переданной таблицы
НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДата();
// Проверяем тип данных
Если ТипЗнч(ПереданныеТовары) = Тип("ТаблицаЗначений") Тогда
НовыйДок.Товары.Загрузить(ПереданныеТовары);
ИначеЕсли ТипЗнч(ПереданныеТовары) = Тип("Массив") Тогда
// Если пришел массив структур
Для Каждого СтрокаМассива Из ПереданныеТовары Цикл
НоваяСтрока = НовыйДок.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаМассива);
КонецЦикла;
КонецЕсли;
НовыйДок.Записать();
КонецЕсли;
КонецЕсли;
Применяя эти методы, мы получаем полный контроль над маршрутизацией данных в КД 2.1. Использование параметров объекта в связке с правильным переопределением флагов поиска и отказов от выгрузки позволяет создавать гибкие архитектуры обмена, генерируя любое количество связанных документов на основе сложной структуры источника.