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