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