Почему в периферийной базе РИБ по организации удаляются контрагенты и как это исправить?

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

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

Механизм возникновения проблемы: почему справочники удаляются

В типовых конфигурациях, таких как 1C:Бухгалтерия (начиная с редакции 2.0 и актуальной 3.0), реализован план обмена с фильтрацией по организации. Под капотом этой подсистемы заложен строгий принцип изоляции данных.

Рассмотрим по шагам, как именно происходит самоудаление:

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

Способ 1. Обеспечение критерия видимости без изменения конфигурации

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

  1. В центральной информационной базе создадим для нужных контрагентов базовые (служебные или основные) договоры, в реквизите Организация которых укажем организацию периферийного узла.
  2. После записи договоров типовые правила обмена зафиксируют изменение и при следующем сеансе выгрузят контрагентов в узел штатно, без отправки команды на удаление.

Способ 2. Корректировка логики отправки данных в плане обмена

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

Разберем логику: вместо директивы удаления укажем платформе игнорировать отправку, если объект не проходит условия фильтрации.


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

КонецПроцедуры

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

Способ 3. Отключение авторегистрации при разовой загрузке

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


НовыйОбъект = Справочники.Контрагенты.СоздатьЭлемент();
// Заполняем реквизиты объекта
НовыйОбъект.Наименование = "Тестовый Контрагент";

// Отключаем регистрацию изменений и проверки при записи
НовыйОбъект.ОбменДанными.Загрузка = Истина;
НовыйОбъект.Записать();

Если объекты уже были загружены стандартными средствами без признака загрузки, очистим таблицу регистрации вручную перед запуском обмена:


ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, Метаданные.Справочники.Контрагенты);

Важное предостережение: если центральный узел в дальнейшем перерегистрирует этих контрагентов (например, при их групповом пересчете или изменении реквизитов), они снова попадут под фильтр и центр вновь отправит команду на удаление в подчиненную базу. Поэтому для постоянной стабильной работы рекомендуется использовать Способ 1 или Способ 2.

Архитектурные риски и рекомендации

Проанализируем ключевые опасности механизма удаления в РИБ:

  1. Риск нарушения ссылочной целостности: Если пользователь в периферийной базе создал документ с контрагентом, у которого еще нет договора, а следом пришел пакет с директивой УдалениеОбъекта, возможны два исхода: аварийное завершение обмена с ошибкой блокировки целостности либо появление битой ссылки вида <Объект не найден> прямо в проведенном документе.
  2. Выбор архитектуры: Если филиалу требуется доступ ко всему массиву справочников головной компании, использование РИБ с отбором по организации является архитектурной ошибкой. В таких сценариях целесообразно переходить либо на полный РИБ с разграничением прав на уровне RLS (ограничение доступа на уровне записей), либо использовать синхронизацию через формат EnterpriseData, где команды физического удаления данных между базами не передаются.
← На главную