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