Как настроить выборочную синхронизацию документов и их движений в РИБ

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При работе с распределенными информационными базами (РИБ) часто возникает задача ограничить передачу данных между узлами. Например, когда из центральной базы в периферийную должны попадать только расчеты с контрагентами, а обратно — только документы поступления. Стандартная синхронизация «из коробки» обычно предполагает полный обмен всеми документами, входящими в состав плана обмена. Рассмотрим, как реализовать выборочный обмен, сохранив конфигурацию на поддержке и избежав типичных ошибок с «битыми» ссылками.

Понимание механизма регистрации данных

Для начала проанализируем, как 1С понимает, что именно нужно отправить в другой узел. В системе существует объект ПланыОбмена, который хранит таблицу изменений. Как только документ записывается, система проверяет, включен ли он в состав плана обмена, и если да, ставит «отметку» о необходимости выгрузки. Настройку этой «отметки» мы можем регулировать с помощью Правил регистрации объектов (ПРО). Это XML-файлы, которые описывают логику регистрации каждого типа метаданных.

Использование правил регистрации объектов

Если конфигурация находится на поддержке, мы не хотим менять программный код в модулях. Вместо этого разберем вариант с редактированием правил регистрации. Эти правила можно выгрузить из базы, отредактировать в специальной конфигурации «Конфигурация: Обмен данными» и загрузить обратно в настройки синхронизации.

Чтобы определить, в какой базе выполняется код (в центральной или периферийной), воспользуемся функцией ПланыОбмена.ГлавныйУзел(). Проанализируем логику: если функция возвращает Неопределено, значит, мы находимся в главной (центральной) базе.

В правилах регистрации для конкретного документа (например, СписаниеСРасчетногоСчета) в обработчике «После обработки» можно прописать следующее условие:


Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
    // Мы в центральной базе.
    // Разрешаем регистрацию только если документ соответствует условию (например, по статье расходов).
    Если Объект.СтатьяРасходов <> Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("НужнаяСтатья") Тогда
        Отказ = Истина;
    КонецЕсли;
Иначе
    // Мы в периферийной базе. 
    // Например, запрещаем выгрузку этого типа документа в центр совсем.
    Отказ = Истина;
КонецЕсли;

Проблема «Объект не найден» и регистрация движений

Многие разработчики сталкиваются с ситуацией, когда сам документ успешно отфильтрован и не попадает в обмен, но в периферийной базе все равно появляются пустые записи в регистрах с надписью <Объект не найден>. Выясним причину этого явления.

Дело в том, что у регистров накопления, сведений и бухгалтерии в метаданных часто стоит свойство «Авторегистрация: Разрешить». Когда документ проводится, он записывает движения в регистры. Система автоматически регистрирует эти движения на узлах обмена независимо от того, зарегистрирован ли сам документ-регистратор. Чтобы решить эту проблему, рассмотрим два способа.

Способ 1: Настройка правил для наборов записей регистров

Это надежный, хотя и трудоемкий путь. Для каждого регистра, в котором появляются «фантомные» записи, нужно настроить правило регистрации. В обработчике «Перед обработкой» или «После обработки» набора записей необходимо проверить регистратор. Проанализируем пример кода для регистра накопления:


// В правилах регистрации для набора записей регистра
Регистратор = Объект.Отбор.Регистратор.Значение;

Если ТипЗнч(Регистратор) = Тип("ДокументСсылка.СписаниеСРасчетногоСчета") Тогда
    // Проверяем те же условия, что и для самого документа
    Если Регистратор.СтатьяРасходов <> Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("НужнаяСтатья") Тогда
        Отказ = Истина;
    КонецЕсли;
КонецЕсли;

Такой подход гарантирует, что если документ не прошел фильтр, то и его движения не будут зарегистрированы и отправлены.

Способ 2: Использование расширений конфигурации

Посмотрим на более современный метод. Если вы не хотите возиться с XML-правилами регистрации, создадим расширение. В расширении можно перехватить событие ПриЗаписи документа и программно управлять регистрацией изменений.

Разберем алгоритм работы в расширении:

  1. Создаем расширение, добавляем в него нужный план обмена и документ.
  2. В модуле документа или в подписке на событие ПриЗаписи пишем код удаления регистрации.

&После("ПриЗаписи")
Процедура Расш_ПриЗаписи(Отказ)
    // Определяем узлы, для которых нужно отменить регистрацию
    Для Каждого Узел Из ПланыОбмена.СинхронизацияДанныхЧерезУниверсальныйФормат.Выбрать() Цикл
        Если Узел = ПланыОбмена.ГлавныйУзел() Тогда 
            Продолжить; // Не трогаем основной узел, если нужно
        КонецЕсли;
        
        Если НЕ Объект.СтатьяРасходов = Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("НужнаяСтатья") Тогда
            // Удаляем регистрацию самого документа
            ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Объект.Ссылка);
            
            // Удаляем регистрацию всех движений документа
            Для Каждого Движение Из Объект.Движения Цикл
                ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Движение);
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

Использование глобальных обработчиков в ПРО

Если регистров много, прописывать условия в каждом — неэффективно. Проанализируем возможность использования раздела «Общие обработчики» в правилах регистрации. В обработчике Перед обработкой правила регистрации объекта можно написать универсальную функцию, которая будет анализировать тип объекта. Если это набор записей регистра, функция будет проверять реквизиты его регистратора по заранее заданному алгоритму. Это сократит объем дублирующего кода в десятки раз.

Важные рекомендации по обслуживанию

При настройке выборочной синхронизации важно помнить о следующих моментах:

Таким образом, комбинируя правила регистрации объектов и проверку через ПланыОбмена.ГлавныйУзел(), мы получаем гибкий инструмент управления потоками данных в РИБ, не нарушая целостности типовой конфигурации.

← На главную