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