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

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

При формировании начального образа подчиненного узла распределенной информационной базы (РИБ) разработчики и администраторы могут столкнуться с крайне необычным поведением: процесс выгрузки прерывается аварийной ошибкой вида «Поле объекта не обнаружено» (например, при обращении к реквизиту МагазинОтправитель или аналогичным полям конкретных документов). При анализе набора записей регистра накопления или сведений в точке останова отладчика обнаруживается парадоксальная ситуация: значение в НаборЗаписей.Отбор.Регистратор.Значение указывает на один документ, а в первой строке НаборЗаписей[0].Регистратор находится совершенно другой документ.

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

Причина возникновения ошибки

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

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

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

ТипРегистратора = ТипЗнч(Объект.Отбор.Регистратор.Значение);

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

Способ 1. Корректировка правил регистрации объектов (быстрое решение)

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

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

Разберем пример безопасной проверки в обработчике правил регистрации:


Если Объект.Количество() > 0 Тогда
    ТипРегистратора = ТипЗнч(Объект[0].Регистратор);
Иначе
    ТипРегистратора = ТипЗнч(Объект.Отбор.Регистратор.Значение);
КонецЕсли;

Если ТипРегистратора = Тип("ДокументСсылка.ПеремещениеТоваров") Тогда
    // Проверка условий выгрузки по реквизитам перемещения
    // ...
КонецЕсли;

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

Способ 2. Обновление версии технологической платформы (рекомендуемое решение)

Поскольку корень проблемы кроется в ошибке ядра платформы при формировании сериализуемого набора, наиболее правильным и надежным решением является смена версии 1С:Предприятия.

  1. Выполним обновление технологической платформы на сервере или локальной машине до актуальных стабильных релизов (ошибка была устранена в последующих сборках платформы 8.3.10 и выше).
  2. Если обновить рабочий сервер СУБД в данный момент регламентно невозможно, выгрузим информационную базу в файл (dt), развернем ее локально на рабочей станции с исправленной версией платформы (например, в файловом варианте) и выполним создание начального образа там.
  3. Полученный начальный образ развернем в целевом магазине или филиале.

Способ 3. Создание подчиненного узла без метода «СоздатьНачальныйОбраз»

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

Вариант А: Инициализация через копию базы данных

  1. Создадим полную копию центральной информационной базы на сервере или в файловом режиме.
  2. Запустим копию базы в режиме 1С:Предприятие с отключенным обменом. Программно снимем признак главного узла через команду: ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
  3. В плане обмена переименуем предопределенный узел (ЭтотУзел), назначив ему код и наименование нового магазина, а узлу центральной базы назначим признак главного узла:
    
    УзелГлавного = ПланыОбмена.СинхронизацияДанныхЧерезУниверсальныйФормат.НайтиПоКоду("ЦБ");
    ПланыОбмена.УстановитьГлавныйУзел(УзелГлавного);
    
  4. Очистим ненужные исторические данные документов и регистров средствами конфигурации или типовыми обработками свертки.

Вариант Б: Инициализация через пустую базу и стандартную синхронизацию

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