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