При работе с распределенными информационными базами (РИБ) программисты часто сталкиваются с ситуацией, когда стандартное поведение системы кажется нелогичным. Одной из таких проблем является автоматическая замена объекта на сообщение об удалении ObjectDeletion в файле обмена, даже если в центральной базе объект всего лишь помечен на удаление, а не удален физически. Рассмотрим подробно, почему это происходит, как работает механизм регистрации изменений и как добиться корректной синхронизации для справочника Спецификации в конфигурации 1С:Управление нашей фирмой (УНФ).
В современных конфигурациях, построенных на «Библиотеке стандартных подсистем» (БСП), процесс обмена данными управляется не только платформой, но и программным слоем — Правилами регистрации объектов (ПРО). Когда мы вносим изменения в объект (например, устанавливаем пометку удаления), платформа регистрирует это изменение для соответствующих узлов обмена. Однако в момент формирования файла обмена (вызова метода ЗаписатьИзменения()) система выполняет дополнительную проверку.
Разберем, что происходит «под капотом»:
ПолныйРегистрация), и в таблицу регистрации изменений записывается ссылка на объект.ObjectDeletion.Это сделано для очистки данных: если объект перестал соответствовать фильтрам (например, поменялась организация или склад), он должен быть удален из узла, где его присутствие более не предусмотрено правилами миграции.
Справочник Спецификации в УНФ является подчиненным справочнику Номенклатура. Его миграция часто жестко связана с владельцем. Проанализируем, почему при установке пометки удаления вместо передачи признака ПометкаУдаления = Истина в файл уходит команда на полное удаление.
Основная причина кроется в обработчике «При обработке» в правилах регистрации. Если в коде этого обработчика прописана логика, которая при наличии пометки удаления исключает узел из списка получателей, платформа интерпретирует это так: «Этого объекта на узле-приемнике быть не должно». В результате вместо образа объекта со всеми реквизитами передается только его ссылка внутри тега удаления.
Рассмотрим пример того, как может выглядеть ошибочный код в правилах регистрации:
// Ошибочная логика в ПРО
Если Источник.ПометкаУдаления Тогда
// Если объект помечен на удаление, мы не добавляем узлы в Получатели
// Платформа видит, что регистрации нет, и отправляет ObjectDeletion
Возврат;
КонецЕсли;
Чтобы точно определить, на каком этапе происходит подмена, выполним следующие шаги:
Шаг 1. Проверка регистрации изменений. Посмотрим, какой объект зафиксирован в таблице регистрации изменений для конкретного узла. Это можно сделать с помощью типовой обработки «Регистрация изменений для обмена» (входит в состав БСП). Если в списке зарегистрированных объектов видна нормальная ссылка (элемент справочника), значит, на этапе записи данных проблем нет.
Шаг 2. Проверка XML-файла обмена. Выгрузим данные в файл и откроем его любым текстовым редактором. Если мы видим структуру:
<v8:ObjectDeletion>
<v8:Ref xmlns="" xsi:type="CatalogRef.Спецификации">guid-объекта</v8:Ref>
</v8:ObjectDeletion>
Это подтверждает, что фильтрация срабатывает в момент выгрузки. Платформа считает, что объект «ушел» из области видимости узла.
Шаг 3. Анализ правил миграции владельца.
Проанализируем связь с владельцем. Если у Номенклатуры (владельца спецификации) также стоит пометка удаления или она не проходит по фильтрам узла, то и подчиненный справочник Спецификации может автоматически отсекаться системой обмена.
Для того чтобы пометка удаления корректно мигрировала в периферийную базу, необходимо убедиться, что помеченный объект по-прежнему попадает в массив Получатели в правилах регистрации.
Разберем правильный подход к написанию обработчика При обработке в правилах регистрации объектов:
Спецификации.Пример кода, обеспечивающего корректную регистрацию:
// Правильная логика регистрации в ПРО
Для Каждого Узел Из СписокВсехУзлов Цикл
// Проверяем условия миграции (например, по организации владельца)
Если ОбъектДолженБытьНаУзле(Источник, Узел) Тогда
// Обязательно добавляем узел, даже если Источник.ПометкаУдаления = Истина
Получатели.Добавить(Узел);
КонецЕсли;
КонецЦикла;
Важный момент: Если вы хотите, чтобы в периферийной базе объект просто «висел» с пометкой удаления, он обязательно должен проходить через фильтры регистрации. Как только алгоритм ПРО скажет «Ложь» для этого объекта, платформа сформирует ObjectDeletion.
Подведем итоги нашего анализа. Появление ObjectDeletion вместо объекта с пометкой удаления — это не ошибка платформы, а работа механизма поддержания целостности данных в РИБ.
Для исправления ситуации необходимо:
ПолныйРегистрация и ПолныйРегистрацияУдаления (убедиться, что справочник в них включен).Следуя этим шагам, мы обеспечим идентичность данных в центральной и периферийной базах, сохранив историю изменений и возможность восстановления объектов из пометок удаления.