Как исключить объект из обмена при удалении, если данные передаются из справочника в регистр сведений?

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

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

В чем причина ошибки синхронизации при удалении объекта

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

<УдалениеОбъекта ТипПриемника="РегистрСведенийЗапись..." ТипИсточника="СправочникСсылка..." УникальныйИдентификатор="..."/>

Выясним причину такого поведения платформы 1С:

  1. Несовместимость типов данных. Служебный узел УдалениеОбъекта всегда содержит атрибут УникальныйИдентификатор. Этот механизм платформы рассчитан строго на ссылочные типы (справочники, документы, планы видов характеристик). Записи регистров сведений являются нессылочными данными — у них нет собственного GUID, а их уникальность определяется ключом записи (периодом и набором измерений). Загрузчик в базе-приемнике не может сопоставить GUID с записью регистра и падает с критической ошибкой.
  2. Механизм «выпадения из отбора» в БСП. Если разработчик устанавливает в Правилах конвертации объектов (ПКО) условие Отказ = Истина при наличии пометки удаления, типовой механизм Библиотеки стандартных подсистем считает, что объект перестал соответствовать условиям выгрузки. Чтобы в базе-приемнике не оставались устаревшие сведения, БСП автоматически формирует команду на удаление объекта на стороне приемника.
  3. Физическое удаление данных. Если элемент справочника удаляется непосредственно (например, через процедуру удаления помеченных объектов), в таблицу изменений плана обмена записывается объект служебного типа УдалениеОбъекта. У такого объекта физически нет реквизита ПометкаУдаления, а есть только свойство Ссылка. Попытка обращения к Объект.ПометкаУдаления в коде вызовет фатальную ошибку.

Способ 1. Настройка правил регистрации объектов (ПРО)

Наиболее правильный подход к решению задачи — предотвратить саму регистрацию изменений еще на этапе записи объекта или при подготовке данных к отправке. Рассмотрим, как настроить ПРО в конфигурации «Конвертация данных».

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

Если же логика требует программной обработки, используем обработчик события Перед обработкой или При обработке. Проверим тип объекта и пометку удаления следующим кодом:


Если ТипЗнч(Объект) = Тип("УдалениеОбъекта") Тогда
    Отказ = Истина;
ИначеЕсли Объект.ПометкаУдаления Тогда
    Отказ = Истина;
КонецЕсли;

Проанализируем контекст выгрузки. В правилах регистрации БСП присутствует булев флаг Выгрузка. Если правило отрабатывает непосредственно в момент формирования исходящего сообщения (когда Выгрузка = Истина), простой Отказ = Истина приведет к формированию пакета удаления. Чтобы исключить генерацию узла УдалениеОбъекта, очистим регистрацию программно:


Если Выгрузка И Объект.ПометкаУдаления Тогда
    ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Объект);
    Отказ = Истина;
КонецЕсли;

Способ 2. Исключение узла в подписке на события источника

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

Разберем по шагам реализацию в подписке на событие ПередУдалением для соответствующего справочника:


// В обработчике подписки исключаем узел плана обмена из получателей
Объект.ОбменДанными.Получатели.Удалить(Узел);

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

Способ 3. Перехват узла удаления в базе-приемнике

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

В конфигурации «Конвертация данных» в обработчике При получении данных об удалении (или в обработчиках загрузки правил обмена) добавим условие отмены удаления для проблемного регистра сведений:


Если ТипПриемника = "РегистрСведенийЗапись.NY_РеестрКонтрагентовВОтношенииКоторыхИнициированаПретензионноИсковаяРабота" Тогда
    Отказ = Истина;
КонецЕсли;

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

Способ 4. Изменение архитектуры ПКО (переход на НаборЗаписей)

Рассмотрим более устойчивый архитектурный подход. Вместо переноса единичной записи РегистрСведенийЗапись перенастроим ПКО на работу с объектом РегистрСведенийНаборЗаписей.

  1. В ПКО в качестве типа объекта-приемника выберем набор записей целевого регистра.
  2. Установим отбор набора по ведущему измерению (например, по ссылке на внутренний документ или контрагента).
  3. Если исходный объект активен — набор заполняется актуальными строками и записывается.
  4. Если объект помечается на удаление — в приемник передается пустой набор записей с установленным отбором. Платформа 1С штатно перезапишет и очистит строки регистра без необходимости генерации узла УдалениеОбъекта.
← На главную