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

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

При настройке обмена данными между информационными базами с помощью конфигурации «Конвертация данных 2.0» нередко возникает задача разделения потоков документов. Типичный пример: из одной центральной базы (например, конфигурации для сельского хозяйства) выгружаются документы сразу в несколько удаленных баз-приемников (например, разные весовые пункты). Чтобы объект загружался только в ту базу, которой он предназначен, разработчики часто добавляют в приемники разделяющие константы и пытаются сопоставить их со свойствами загружаемого документа.

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

Анализ типичных ошибок в обработчиках загрузки

Рассмотрим фрагмент кода, который разработчики нередко пытаются поместить в обработчик события При загрузке:


Значение = Константы.ЭтоВесоваяРаздолье.Получить();
Если Не Значение = Приемник.ЭтоВесоваяРаздолье Тогда
    Отказ = Истина;
КонецЕсли;

Выясним причину, почему такая конструкция не работает:

  1. Неверная область видимости контекстных переменных: переменные Источник и Приемник доступны исключительно на стороне выгрузки данных. На стороне загрузки создаваемый или найденный элемент доступен через переменную Объект.
  2. Отсутствие параметра Отказ в обработчике «При загрузке»: в данном событии платформа не предоставляет параметр отмены. Присваивание значения переменной Отказ просто создает локальную переменную внутри процедуры, которая никак не влияет на дальнейший процесс импорта. Кроме того, само событие срабатывает сразу после попытки поиска объекта, когда входящие свойства из XML-файла еще не перенесены в реквизиты.
  3. Ограничения обработчика «Перед загрузкой»: несмотря на то, что параметр Отказ здесь доступен, сам Объект еще не инициализирован, а доступ к его реквизитам напрямую невозможен без низкоуровневого парсинга XML-потока.

Способ 1. Использование обработчика «После загрузки» ПКО

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

Если реквизит ЭтоВесоваяРаздолье переносится штатно через правило конвертации свойства (ПКС), код обработчика После загрузки в ПКО будет выглядеть следующим образом:


ЗначениеКонстанты = Константы.ЭтоВесоваяРаздолье.Получить();

Если ЗначениеКонстанты <> Объект.ЭтоВесоваяРаздолье Тогда
    Отказ = Истина;
КонецЕсли;

При установке флага Отказ = Истина текущий документ не будет сохранен в базе-приемнике.

Способ 2. Передача признака через параметры объекта

Иногда нет необходимости добавлять отдельный реквизит в документ базы-приемника или требуется выполнить проверку до того, как реквизиты будут записаны в структуру объекта. В таком случае значение передается через специальный механизм параметров.

Разберем реализацию этого способа по шагам:

  1. В ПКС соответствующего реквизита на стороне источника устанавливаем флаг Передавать данные в параметр и задаем имя, например, ЭтоВесоваяРаздолье.
  2. На стороне приемника в обработчике После загрузки извлекаем значение из системной коллекции ПараметрыОбъекта, представляющей собой Соответствие:

Если ПараметрыОбъекта <> Неопределено Тогда
    ЗначениеФлага = ПараметрыОбъекта["ЭтоВесоваяРаздолье"];
    Если ЗначениеФлага <> Константы.ЭтоВесоваяРаздолье.Получить() Тогда
        Отказ = Истина;
    КонецЕсли;
КонецЕсли;

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

Способ 3. Оптимизация: фильтрация данных на стороне источника

Хотя отмена записи в базе-приемнике решает функциональную задачу, с точки зрения архитектуры она создает лишнюю нагрузку: источник тратит ресурсы на сериализацию данных в XML, файл передается по каналам связи, а приемник разбирает весь поток, чтобы в итоге отказаться от записи.

Проанализируем более производительное решение — отсекать ненужные документы еще на этапе выгрузки:

  1. При выгрузке через универсальную обработку: в ПКО в обработчике Перед выгрузкой достаточно проверить значение реквизита источника:
    
    Если Не Источник.ЭтоВесоваяРаздолье Тогда
        Отказ = Истина;
    КонецЕсли;
    
  2. При использовании планов обмена: создаются два отдельных узла плана обмена под каждую весовую. Разделение потоков настраивается в правилах регистрации объектов (ПРО) или в подписке на событие ПередЗаписьюДокумента, чтобы документ регистрировался к выгрузке только на соответствующем узле.

Важные особенности при отмене загрузки

Применяя Отказ = Истина на стороне приемника, важно помнить о следующих нюансах:

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

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

← На главную