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