Почему не передаются ИсходящиеДанные из ПВД в ВходящиеДанные ПКО и как это исправить?

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

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

Анализ механизма передачи данных между обработчиками

Для начала проанализируем стандартную логику взаимодействия. В правилах выгрузки данных (ПВД) существует обработчик «Перед обработкой». Предполагается, что если мы создадим там структуру и наполним её данными, то при вызове ПКО эти данные автоматически станут доступны. Рассмотрим типичный пример кода, который пишут разработчики в ПВД:


// Обработчик ПВД "Перед обработкой"
ИсходящиеДанные = Новый Структура;
ИсходящиеДанные.Вставить("ДополнительныйПараметр", "ВажноеЗначение");
ИсходящиеДанные.Вставить("СсылкаНаОбъект", Источник.Ссылка);

Затем в ПКО в обработчике «Перед выгрузкой» мы ожидаем увидеть эти данные:


// Обработчик ПКО "Перед выгрузкой"
Если ВходящиеДанные <> Неопределено Тогда
    Сообщить(ВходящиеДанные.ДополнительныйПараметр);
Иначе
    // Мы часто попадаем сюда, хотя данные в ПВД были заполнены
    Сообщить("Входящие данные потеряны!");
КонецЕсли;

Выясним причину такого поведения. Проблема может скрываться либо в логике вызова (произвольный алгоритм против стандартной выборки), либо в ошибке самого ядра выгрузки — обработки УниверсальныйОбменДаннымиXML.

Выявление ошибки в типовой обработке «Универсальный обмен данными XML»

Проанализируем код типовой обработки УниверсальныйОбменДаннымиXML, которая используется для выполнения обмена. Если мы заглянем внутрь с помощью отладчика, то обнаружим критическую недоработку в процедуре ВыгрузкаОбъектаВыборки. Посмотрим на фрагмент кода, который отвечает за передачу данных в ВыгрузитьПоПравилу:


Процедура ВыгрузкаОбъектаВыборки(Объект, Правило, Свойства=Неопределено, 
                                ВходящиеДанные=Неопределено, 
                                ВыборкаДляВыгрузкиДанных = Неопределено)
    // ... некоторый код ...
    
    // ВНИМАНИЕ: Здесь кроется ошибка!
    ИсходящиеДанные = Неопределено; 
    
    // ... некоторый код ...
    
    // Вызывается процедура выгрузки, но в параметр ИсходящиеДанные 
    // передается только что обнуленная переменная вместо ВходящиеДанные
    ВыгрузитьПоПравилу(Объект, , ИсходящиеДанные, , ИмяПКО, УзелСсылки, , , , ВыборкаДляВыгрузкиДанных);
    
КонецПроцедуры

Как мы видим, в коде происходит жесткое обнуление переменной ИсходящиеДанные непосредственно перед вызовом основной функции выгрузки. Это приводит к тому, что любые данные, переданные из ПВД в эту процедуру, просто игнорируются. Чтобы исправить это поведение, нам необходимо изменить вызов функции так, чтобы она использовала ВходящиеДанные, пришедшие в процедуру ВыгрузкаОбъектаВыборки.

Решение: если у вас есть возможность редактировать обработку обмена (она не зашита в ядро закрытой конфигурации), замените в указанном вызове ИсходящиеДанные на ВходящиеДанные. После этого проброс параметров заработает корректно.

Особенности работы при произвольном алгоритме

Если в ПВД выбран способ выборки «Произвольный алгоритм», мы берем на себя ответственность за вызов выгрузки. В этом случае крайне важно правильно передать параметры в функцию ВыгрузитьПоПравилу. Рассмотрим, как это сделать методически верно:


// ПВД: Произвольный алгоритм
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура");
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    // Формируем структуру данных для ПКО
    СтруктураДляПКО = Новый Структура("СпецЦена, СкладДоставки", 1500, СкладСсылка);
    
    // Важно: третий параметр функции - это и есть наши ИсходящиеДанные
    ВыгрузитьПоПравилу(Выборка.Ссылка, , СтруктураДляПКО, , "Номенклатура");
КонецЦикла;

В данном примере мы явно передаем структуру в третий параметр. В ПКО «Номенклатура» эти данные будут доступны в переменной ВходящиеДанные. Если вы вызываете ВыгрузитьПоПравилу и пропускаете третий параметр, данные в ПКО не попадут.

Нюансы миграции данных в конфигурациях на БСП 3.x

В современных конфигурациях, использующих актуальные версии Библиотеки стандартных подсистем (БСП), механизмы обмена могут вести себя иначе. Проанализируем опыт разработчиков, работающих с планами обмена в БСП 3.х. В некоторых случаях стандартный механизм ИсходящиеДанные игнорируется системой из-за особенностей сериализации контекста при фоновом выполнении задач.

Рассмотрим альтернативный способ, который работает в БСП: использование переменной ВходящиеПравила в обработчике ПВД «Перед выгрузкой». Несмотря на то, что это противоречит справочной информации самой «Конвертации данных», практика показывает, что запись дополнительных параметров непосредственно в локальный контекст правил в этом обработчике позволяет «протащить» их до ПКО.

Однако более надежным и современным методом для БСП является использование Дополнительных свойств самого объекта. Разберем этот метод подробнее.

Использование ДополнительныхСвойств как альтернативный транспорт

Если вам нужно передать ссылки или сложные структуры вместе с объектом справочника или документа, и стандартные ИсходящиеДанные не срабатывают, воспользуемся механизмом платформы ДополнительныеСвойства. Этот метод особенно хорош тем, что данные «прилипают» к самому объекту Источник и гарантированно проходят через все процедуры выгрузки.

Посмотрим на реализацию в ПВД:


// ПВД "Перед обработкой" или "Перед выгрузкой"
// Добавляем данные прямо в объект 1С
ОбъектСсылка = Источник.ПолучитьОбъект(); 
// Внимание: метод требует получения объекта, что может снизить производительность
ОбъектСсылка.ДополнительныеСвойства.Вставить("МойПараметр", СсылкаНаДругойОбъект);

Затем в ПКО мы извлекаем эти данные:


// ПКО "Перед выгрузкой"
Если Источник.ДополнительныеСвойства.Свойство("МойПараметр") Тогда
    Значение = Источник.ДополнительныеСвойства.МойПараметр;
    // Используем полученное значение
КонецЕсли;

Этот метод считается «силовым», так как он обходит механизмы конвертации данных, используя стандартные возможности платформы 1С. Мы рекомендуем использовать его в тех случаях, когда правка типовой обработки УниверсальныйОбменДаннымиXML невозможна.

Резюме и рекомендации

Подведем итоги нашего анализа ситуации с передачей данных между ПВД и ПКО:

  1. Проверьте версию обработки: В большинстве случаев проблема вызвана программной ошибкой в УниверсальныйОбменДаннымиXML, где ИсходящиеДанные обнуляются в процедуре ВыгрузкаОбъектаВыборки.
  2. Для произвольных алгоритмов: Всегда явно передавайте структуру данных в третий параметр функции ВыгрузитьПоПравилу.
  3. Для БСП 3.x: Если стандартный метод не работает, попробуйте использовать контекст ВходящиеПравила или передачу через ДополнительныеСвойства объекта.
  4. Глобальные параметры: Если данные не уникальны для каждого объекта, а являются общими для всей выгрузки, используйте структуру Параметры, инициализируемую в обработчике «Перед выгрузкой данных» всей конвертации.

Соблюдение этих правил позволит вам надежно передавать любую служебную информацию (ссылки на регистры, дополнительные признаки, аналитику) из правил выгрузки в правила конвертации объектов, обеспечивая корректную работу сложных обменов данными.

← На главную