При настройке правил обмена в конфигурации «Конвертация данных 2.0» (КД 2.0) часто возникает задача: перенести документ из базы-источника в базу-приёмник, но при этом заполнить определенный реквизит (например, Контрагент или Склад) значением по умолчанию только в том случае, если документ создается заново. Если документ уже существует в базе-приёмнике, его реквизит перезаписывать не требуется.
Разберем детально, почему проверки со стороны источника (в обработчике «Перед выгрузкой») не работают в этой ситуации, и рассмотрим программные и настройки механизмы КД 2.0 для решения этой задачи.
Проанализируем частую ошибку разработчиков: попытку проверить наличие объекта или запустить функции поиска в обработчиках выгрузки (например, «Перед выгрузкой» в ПКС). На этапе выгрузки данных из информационной базы-источника обработка обмена ничего не знает о содержимом базы-приёмника. Выгрузка создает XML-файл с данными, а поиск элементов происходит уже на стороне приёмника во время загрузки.
Наиболее наглядный способ заполнения реквизита при создании объекта — использование специального обработчика «После загрузки» в Правиле конвертации объектов (ПКО).
В этом обработчике доступна системная переменная ОбъектНайден, которая имеет значение Ложь, если документ не был найден в базе по УИД или полям поиска и создается с нуля.
Рассмотрим порядок действий:
ЗаказПокупателя).
Если Не ОбъектНайден Тогда
// Получаем ссылку на предопределенный элемент или ищем по коду
Объект.Контрагент = Справочники.Контрагенты.НайтиПоКоду("00002");
КонецЕсли;
Важные нюансы при написании кода:
1. Заполнение ссылочным типом: Переменной Объект.Контрагент нужно присваивать именно ссылку на объект (СправочникСсылка.Контрагенты), а не строковое наименование или код.
2. Обращение к предопределенным элементам: Если в базе-приёмнике элемент является предопределенным, безопаснее использовать функцию ПредопределенноеЗначение() или прямое обращение к имени элемента:
Если Не ОбъектНайден Тогда
Объект.Контрагент = ПредопределенноеЗначение("Справочник.Контрагенты.НеизвестныйПокупатель");
КонецЕсли;
3. Явная запись объекта не требуется: Внутри обработчика «После загрузки» вызывать метод Объект.Записать() не нужно. Обработка УниверсальныйОбменДаннымиXML автоматически сохранит созданный или отредактированный объект после выполнения кода обработчика. Лишняя запись приводит к повторным вызовам подписок на события и снижает скорость обмена.
В «Конвертации данных 2.0» предусмотрен штатный механизм, позволяющий избежать написания программного кода в обработчиках загрузки.
Разберем шаг за шагом настройку ПКС:
Контрагент).
Значение = "00002"; // Если для ПКС задано правило поиска по коду
// Или через выражение:
Выражение = "Справочники.Контрагенты.НеизвестныйПокупатель";
При такой настройке логика работы платформы выглядит следующим образом:
Если значение для заполнения должно динамически определяться на стороне источника (например, браться из константы или настройки узла обмена), его удобно передать в базу-приёмник через структуру параметров.
1. В источнике в обработчике «При выгрузке» ПКО передаем параметр:
Параметры.Вставить("ОсновнойКонтрагент", Константы.ОсновнойПокупатель.Получить());
2. В приёмнике в обработчике «После загрузки» ПКО принимаем параметр и заполняем реквизит:
Если Не ОбъектНайден Тогда
ЗначениеПараметра = Неопределено;
Если ПараметрыОбъекта.Свойства().Свойство("ОсновнойКонтрагент", ЗначениеПараметра) Тогда
Объект.Контрагент = ЗначениеПараметра;
КонецЕсли;
КонецЕсли;
Таким образом, для заполнения реквизита только при создании нового объекта можно использовать как программный подход с проверкой Не ОбъектНайден в обработчике «После загрузки», так и штатную настройку флага перезаписи свойства в ПКС.