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