Почему в трехуровневом РИБ 1С:Розница пропадают движения документов и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:Розница Торговля и дистрибуция
← На главную

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

Механизм миграции данных в РИБ и природа возникновения ошибки

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

Когда используется многоуровневая каскадная схема обмена данными, вступает в силу внутренняя специфика сериализации платформы «1С:Предприятие» и правил регистрации объектов (ПРО):

  1. Порядок чтения данных из XML-пакета: Платформа выгружает данные в сообщение обмена в порядке обхода внутренних таблиц регистрации изменений. В подавляющем большинстве случаев наборы записей регистров выгружаются и считываются в базе-приемнике раньше, чем сам объект документа-регистратора.
  2. Неразрешенные ссылки в промежуточном узле: При загрузке набора записей в базу региона в поле Регистратор передается ссылка на документ (GUID). Однако сам документ физически еще не записан в базу данных узла «Область».
  3. Сбой фильтрации в правилах регистрации объектов: В планах обмена по магазинам в конфигурации «1С:Розница» движения регистров фильтруются в зависимости от магазина. Алгоритм регистрации обращается к реквизитам документа через точку, например: НаборЗаписей.Отбор.Регистратор.Значение.Магазин или Склад. Поскольку сам документ в этот момент еще отсутствует в базе данных, платформа возвращает пустую ссылку или Неопределено. В результате фильтрация не срабатывает, и набор записей просто не становится в очередь регистрации на подчиненный узел третьего уровня («Магазин»).
  4. Загрузка документа без проведения: Далее из XML-сообщения считывается сам документ. Он успешно записывается и встает в очередь отправки на узел магазина. Попадая в магазин, документ загружается с установленным свойством ОбменДанными.Загрузка = Истина. При таком режиме стандартное проведение не вызывается, а наборы записей так и не были переданы из промежуточного узла. Документ остается проведенным лишь формально, без фактических записей в регистрах.

Диагностика проблемы: пошаговый анализ обмена

Разберем по шагам, как локализовать место сбоя и убедиться в том, на каком этапе отсекаются движения:

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

Способ 1. Корректировка архитектуры планов обмена (рекомендуемый подход)

Типовой план обмена «По магазину» в конфигурации «1С:Розница» изначально проектировался разработчиками под классическую топологию «звезда» в два уровня: центральный офис и магазины. Использование этого плана обмена одновременно на двух плечах («Центр — Область» и «Область — Магазин») создает конфликт механизмов отбора.

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

  1. Для связи верхнего уровня «Центр — Области» настроим план обмена Полный без фильтрации данных по конкретным торговым точкам. Все документы и их наборы записей будут транслироваться в базы регионов без исключений и сложных условий в ПРО.
  2. Для связи «Область — Магазины» используем типовой план обмена По магазину. В этом случае в промежуточной базе уже будут находиться все объекты, реквизиты регистратора будут доступны без ошибок, и фильтрация движений по магазинам отработает корректно.

Способ 2. Программная дорегистрация движений в подписке на событие

Если изменить состав планов обмена невозможно, доработаем логику регистрации объектов в промежуточном узле. Создадим подписку на событие ПриЗаписи для документов, участвующих в обмене. Когда документ уже физически записан в промежуточную базу, мы гарантированно можем прочитать его реквизиты и зарегистрировать движения на подчиненные узлы.

Посмотрим на пример кода в общем модуле, вызываемом из подписки на событие:


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

Способ 3. Восстановление движений в существующих базах магазинов

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

  1. Пакетная дорегистрация движений из промежуточного узла: В базе «Область» напишем и выполним внешнюю обработку. С помощью метода ПланыОбмена.ЗарегистрироватьИзменения(УзелМагазина, НаборЗаписей) принудительно поставим в очередь отправки движения за нужный период. После очередного сеанса обмена платформа доставит недостающие проводки в магазин.
  2. Групповое перепроведение на стороне магазина: Метод подходит только в том случае, если в узле магазина не закрыт период запрета редактирования и присутствуют все необходимые аналитические данные для корректного формирования движений (например, партии или себестоимость, которые часто исключаются из обмена с периферийными узлами).
← На главную