Как выгрузить объект целиком по ссылке в Конвертации Данных 3.0 и обеспечить срабатывание стандартных обработчиков на приемнике?

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

При работе с обменами данными в 1С:Предприятии 8.3, особенно с Конвертацией Данных 3.0 (КД3), часто возникает необходимость выгружать связанные объекты не просто по их ключевым свойствам (ссылкам), а целиком – со всеми реквизитами и с отработкой типовых процедур конвертации на стороне приемника. Эта задача аналогична функционалу ВыгрузитьОбъект из КД2, но в КД3 реализуется иначе. Давайте подробно разберем, как мы можем достичь такого поведения.

Основной вопрос, который нас интересует: можно ли выгрузить объект целиком (по ссылке), например, номенклатуру вместе с документом, таким образом, чтобы на стороне приемника для выгруженной номенклатуры сработали все настроенные процедуры конвертации и записи, а не только передались ключевые свойства? Также, мы хотим понять, как передать дополнительные данные вместе с таким "выгружаемым по ссылке" объектом.

Рассмотрим несколько аспектов и подходов к решению этой задачи в КД3.

Обеспечение полной выгрузки связанных объектов через правила конвертации

В КД3 подход к обработке ссылочных объектов существенно отличается от КД2. Если в КД2 мы могли явно вызывать ВыгрузитьОбъект, чтобы принудительно выгрузить связанный объект со всеми его правилами, то в КД3 эта логика глубже интегрирована в механизмы XDTO и Правил Конвертации Объектов (ПКО) / Правил Определения Данных (ПОД). Если объект, на который ссылается основной выгружаемый объект, уже описан в правилах обмена, КД3 стремится выгрузить его данные в соответствии с этими правилами, преобразуя свойства, а не только идентификаторы.

  1. Настройка Правил Конвертации Объектов (ПКО) и Правил Определения Данных (ПОД):

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

    Внутри ПКО или ПОД для свойства-ссылки (например, реквизита "Номенклатура" в документе) вы можете указать, как именно должна происходить конвертация этой ссылки. КД3 по умолчанию пытается найти соответствующее ПКО для типа ссылочного объекта. Если ПКО настроено на полную выгрузку (т.е., сопоставлены все необходимые реквизиты), то данные объекта будут выгружены, а не только его GUID.

    Как это работает: Когда основной объект (например, Документ) выгружается, КД3 анализирует его реквизиты. Если реквизит является ссылкой на другой объект (например, Справочник.Номенклатура), система ищет ПКО для типа "Справочник.Номенклатура". Если такое ПКО найдено и настроено для конвертации свойств, КД3 инициирует процесс конвертации и выгрузки этого связанного объекта в составе сообщения обмена.

  2. Срабатывание типовых процедур на приемнике:

    На стороне приемника стандартные обработчики событий, такие как _ПриКонвертацииДанныхXDTO(ДанныеXDTO, ПолученныеДанные, КомпонентыОбмена) и _ПередЗаписьюПолученныхДанных(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена), срабатывают, когда КД3 осуществляет создание или обновление объекта в информационной базе приемника. Это происходит независимо от того, был ли объект выгружен "самостоятельно" (по регистрации в плане обмена) или "по ссылке" в составе другого объекта, при условии, что для него применен соответствующий цикл конвертации. Главное условие – КД3 должна получить достаточно данных для создания или обновления объекта, а не только его ссылки, что достигается корректной настройкой ПКО.

    Таким образом, если вы корректно настроили ПКО для связанного объекта, на стороне приемника он будет обработан как полноценный объект, и все необходимые обработчики сработают.

  3. Регистрация связанных объектов:

    Как было предложено в одном из сообщений, при регистрации основного документа, можно программно регистрировать и его связанную номенклатуру. Это гарантирует, что номенклатура будет выгружена как самостоятельный объект по своим правилам, а ссылка на нее в документе будет корректно обработана. Этот подход может быть полезен, если вы хотите обеспечить независимую выгрузку связанных объектов и их гарантированную обработку — для автоматизации этого процесса есть обработка массовой регистрации объектов на узлах планов обмена.

    Например, в обработчике события регистрации основного документа (или в подписке на событие):

    
    Процедура ПриРегистрацииИзмененийДокументЗаказПокупателя(Источник, Отказ, ЗарегистрированныеИзменения)
        Для Каждого СтрокаТабличнойЧасти Из Источник.Товары Цикл
            Если СтрокаТабличнойЧасти.Номенклатура.ЭтоНовый() Или ИзменениеОбъекта.ОбъектИзменен(СтрокаТабличнойЧасти.Номенклатура) Тогда
                // Регистрируем номенклатуру для обмена
                ПланыОбмена.ЗарегистрироватьИзменение(НашУзелОбмена, СтрокаТабличнойЧасти.Номенклатура);
            КонецЕсли;
        КонецЦикла;
    КонецПроцедуры
    

    Мы должны быть внимательны, чтобы избежать циклических ссылок и избыточной регистрации.

Программная выгрузка объекта по ссылке с использованием ОбменДаннымиXDTOСервер.ВыгрузкаОбъектаВыборки

В КД3 для программной выгрузки объекта вы можете использовать процедуру ОбменДаннымиXDTOСервер.ВыгрузкаОбъектаВыборки(КомпонентыОбмена, Объект). Эта процедура действительно предназначена для выгрузки объекта, но её поведение может отличаться от автоматической выгрузки по плану обмена, особенно в части срабатывания событий.

  1. Назначение процедуры:

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

  2. Особенности поведения:

    При использовании ВыгрузкаОбъектаВыборки объект обрабатывается как часть текущей транзакции обмена, но не всегда гарантирует полный цикл преобразования, аналогичный объектам, зарегистрированным самостоятельно через планы обмена. Важно понимать, что эта процедура "добавляет" данные объекта в XDTO-пакет, используя существующие ПКО/ПОД. Если ПКО для типа объекта настроено корректно, он будет выгружен полностью. Если нет – то, возможно, только ключевые поля.

    Срабатывание обработчиков на приемнике для объекта, выгруженного таким способом, также зависит от того, как КД3 интерпретирует полученные XDTO-данные. Если данные достаточно полны и соответствуют ожидаемой структуре, то стандартные обработчики будут вызваны.

  3. Применение:

    Мы можем использовать эту процедуру в обработчиках событий выгрузки основного объекта (например, в _ПриВыгрузке или _ПослеВыгрузки соответствующего ПКО), чтобы явно добавить связанные объекты, которые по какой-то причине не были бы выгружены автоматически или требуют специальной обработки.

    
    // Пример использования в обработчике ПКО для документа
    Процедура Документ_ПриВыгрузке(ДанныеОбъекта, Параметры, КомпонентыОбмена)
        // Допустим, у нас есть реквизит в документе, который ссылается на Номенклатуру
        // и мы хотим убедиться, что она выгружена целиком.
        Если НЕ ДанныеОбъекта.Номенклатура.Пустая() Тогда
            // Вызываем процедуру для выгрузки связанной номенклатуры
            // КомпонентыОбмена - это та же структура, через которую мы работаем
            ОбменДаннымиXDTOСервер.ВыгрузкаОбъектаВыборки(КомпонентыОбмена, ДанныеОбъекта.Номенклатура);
        КонецЕсли;
    КонецПроцедуры
    

    Важное замечание: При этом подходе (для реализации которого пригодится специализированный редактор кода), убедитесь, что для выгружаемого таким образом объекта (в примере - Номенклатура) существует корректно настроенное ПКО, которое обеспечит полную конвертацию реквизитов.

Передача дополнительной информации через КомпонентыОбмена

Часто возникает потребность передать вместе с выгружаемым объектом какую-то контекстную или вспомогательную информацию, которая не является реквизитом самого объекта, но необходима для корректной обработки на стороне приемника. Например, нам нужно взять реквизит из основного документа и отправить его вместе с объектом, который выгружается по ссылке, чтобы потом использовать эти данные на приемнике, возможно, для заполнения поля AdditionalInfo или других вспомогательных реквизитов.

Как было найдено в обсуждении, структура КомпонентыОбмена является очень гибким инструментом для этой цели. Она представляет собой структуру, которую КД3 передает по цепочке обработки данных и которая доступна как на стороне источника, так и на стороне приемника в различных обработчиках событий.

  1. Добавление данных на стороне источника:

    На стороне выгрузки (в обработчиках ПКО или ПОД) мы можем добавить в структуру КомпонентыОбмена любые данные, которые нам нужны:

    
    // В обработчике ПКО для Документа, например, "_ПриВыгрузке"
    Процедура Документ_ПриВыгрузке(ДанныеОбъекта, Параметры, КомпонентыОбмена)
        // Мы хотим передать какой-то специфический реквизит документа
        // вместе с выгружаемой Номенклатурой.
        // Например, "ВидОперации" документа, который нужен для Номенклатуры.
        КомпонентыОбмена.Вставить("ВидОперацииДокумента", ДанныеОбъекта.ВидОперации);
                
        // Если мы выгружаем номенклатуру программно
        ОбменДаннымиXDTOСервер.ВыгрузкаОбъектаВыборки(КомпонентыОбмена, ДанныеОбъекта.Номенклатура);
                
        // Также можно добавить данные, специфичные для конкретного элемента Номенклатуры
        // Если Номенклатура передается по ссылке, то эти данные
        // будут доступны в контексте общего обмена.
        // Для более специфичной передачи, можно использовать массив или структуру в КомпонентыОбмена
        Если НЕ КомпонентыОбмена.Свойство("ДополнительныеДанныеПоНоменклатуре") Тогда
            КомпонентыОбмена.Вставить("ДополнительныеДанныеПоНоменклатуре", Новый Соответствие);
        КонецЕсли;
        КомпонентыОбмена.ДополнительныеДанныеПоНоменклатуре.Вставить(
            ДанныеОбъекта.Номенклатура.УникальныйИдентификатор(), // Ключ для привязки к конкретной номенклатуре
            "ПроизвольнаяСтрокаДляНоменклатуры_" + ДанныеОбъекта.Номенклатура.Наименование
        );
    КонецПроцедуры
    

    В этом примере мы добавляем ВидОперацииДокумента в корень структуры КомпонентыОбмена. Если нам нужно передать специфичные данные для *каждой* номенклатуры, которая выгружается по ссылке, мы можем использовать более сложную структуру, например, Соответствие, где ключом будет уникальный идентификатор номенклатуры, а значением — передаваемые данные.

  2. Доступ к данным на стороне приемника:

    На стороне приемника, в обработчиках событий (например, _ПриКонвертацииДанныхXDTO или _ПередЗаписьюПолученныхДанных) для объекта, который был выгружен по ссылке (в нашем случае, Номенклатура), мы можем получить доступ к этим данным:

    
    // В обработчике ПКО для Номенклатуры, например, "_ПриКонвертацииДанныхXDTO"
    Процедура Номенклатура_ПриКонвертацииДанныхXDTO(ДанныеXDTO, ПолученныеДанные, КомпонентыОбмена)
        // Проверяем наличие наших данных
        Если КомпонентыОбмена.Свойство("ВидОперацииДокумента") Тогда
            ПереданныйВидОперации = КомпонентыОбмена.ВидОперацииДокумента;
            // Используем переданный вид операции для каких-либо действий
            // Например, устанавливаем реквизит ПолученныеДанные.ВидОперации = ПереданныйВидОперации;
        КонецЕсли;
    
        // Доступ к специфичным данным для этой номенклатуры
        Если КомпонентыОбмена.Свойство("ДополнительныеДанныеПоНоменклатуре") Тогда
            ТекущаяНоменклатураGUID = ПолученныеДанные.УникальныйИдентификатор();
            Если КомпонентыОбмена.ДополнительныеДанныеПоНоменклатуре.Содержит(ТекущаяНоменклатураGUID) Тогда
                ДопДанные = КомпонентыОбмена.ДополнительныеДанныеПоНоменклатуре.Получить(ТекущаяНоменклатураGUID);
                // Используем ДопДанные, например, для заполнения AdditionalInfo
                ПолученныеДанные.Комментарий = ДопДанные;
            КонецЕсли;
        КонецЕсли;
    КонецПроцедуры
    
    // Или в "_ПередЗаписьюПолученныхДанных"
    Процедура Номенклатура_ПередЗаписьюПолученныхДанных(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена)
        Если КомпонентыОбмена.Свойство("ВидОперацииДокумента") Тогда
            ДанныеИБ.ВидОперации = КомпонентыОбмена.ВидОперацииДокумента;
        КонецЕсли;
        // И так далее для других данных...
    КонецПроцедуры
    

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

Общие рекомендации и лучшие практики

  1. Комплексный подход: Для достижения желаемого эффекта — полной выгрузки объекта по ссылке с отработкой типовых процедур на приемнике — в КД3 рекомендуется сочетать несколько подходов. В первую очередь, это корректная настройка ПКО/ПОД для всех связанных объектов. Это основа для автоматической и правильной конвертации, а также поддержания ссылочной целостности.
  2. Использование `КомпонентыОбмена` для контекста: Если требуются дополнительные данные, которые не являются частью структуры выгружаемого объекта, но важны для его обработки на приемнике, используйте КомпонентыОбмена. Мы можем вложить в эту структуру соответствия или массивы для более сложной передачи контекста.
  3. Программная выгрузка как дополнение: ОбменДаннымиXDTOСервер.ВыгрузкаОбъектаВыборки используем, когда нам нужно принудительно выгрузить объект, который не был бы включен в обмен автоматически, или когда требуется особая логика выгрузки. Всегда проверяйте, что для такого объекта есть настроенное ПКО.
  4. Тестирование: Всегда тщательно тестируйте сценарии обмена. Проверяйте, что все необходимые реквизиты передаются, что обработчики событий срабатывают в нужный момент, и что данные корректно записываются на стороне приемника. Используйте отладчик для контроля содержимого КомпонентыОбмена и промежуточных данных.

Таким образом, в Конвертации Данных 3.0 мы можем добиться полной выгрузки объектов по ссылке с отработкой стандартных обработчиков приемника, используя мощь правил конвертации (ПКО/ПОД) и гибкость структуры КомпонентыОбмена для передачи дополнительной информации. Процедура ОбменДаннымиXDTOСервер.ВыгрузкаОбъектаВыборки служит дополнительным инструментом для программного управления составом выгружаемых данных.

← На главную