Как перенести помеченные на удаление объекты при обмене через EnterpriseData?

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

При организации обмена данными между типовыми конфигурациями 1С с использованием универсального формата EnterpriseData (ED) разработчики часто сталкиваются с неприятной особенностью: объекты, помеченные на удаление в базе-источнике, отказываются переноситься в базу-приемник либо переносятся некорректно (теряя пометку удаления). Настроек, позволяющих регулировать это поведение напрямую в пользовательском интерфейсе синхронизации, не предусмотрено.

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

Почему возникает проблема: анализируем архитектуру EnterpriseData

Для того чтобы понять причину такого поведения системы, нам необходимо обратиться к архитектуре формата EnterpriseData и механизмам пакетов XDTO. В стандартных схемах обмена для большинства справочников и документов разработчиками фирмы «1С» изначально не заложено свойство ПометкаУдаления (или DeletionMark) внутри структуры самого бизнес-объекта.

Логика работы платформы при использовании «Конвертации данных 3» (КД3) построена на следующих принципах:

Однако на практике эта схема часто дает сбой. Либо правила регистрации объектов (ПРО) полностью блокируют регистрацию помеченных на удаление элементов, либо логика менеджера обмена не преобразует эти данные в команду <УдалениеОбъекта> должным образом. В результате база-приемник просто ничего не получает, и объект там остается активным.

Попытка «в лоб» заставить систему выгружать помеченный объект как обычный (путем обхода стандартных алгоритмов в общем модуле ОбменДаннымиXDTOСервер) приводит к тому, что объект загружается в приемник, но... без пометки на удаление. Это происходит именно потому, что в XDTO-пакете этого объекта нет поля для передачи признака удаления, и приемник записывает его как обычный новый или обновленный элемент.

Давайте рассмотрим три профессиональных способа решения этой проблемы.

Способ 1. Настройка штатного механизма через секцию «УдалениеОбъекта»

Этот способ является наиболее правильным с точки зрения архитектуры 1С, так как он задействует стандартный механизм платформы. Наша задача — заставить систему сгенерировать правильную XML-структуру удаления. Для этого выполним два основных шага.

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

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

Шаг 2. Доработка менеджера обмена на стороне источника

В модуле МенеджерОбменаЧерезУниверсальныйФормат на стороне источника найдем обработчик Правил обработки данных (ПОД) для нужного объекта (например, ПОД_Справочник_Контрагенты_Отправка_ПриОбработке) и пропишем алгоритм, перенаправляющий выгрузку в русло стандартного удаления:


Если ДанныеИБ.ПометкаУдаления Тогда
    // Отключаем стандартные правила конвертации (ПКО) для этого объекта,
    // чтобы он не выгружался как обычный элемент
    Для Каждого ТекущееПКО Из ИспользованиеПКО Цикл
        ИспользованиеПКО[ТекущееПКО.Ключ] = Ложь;
    КонецЦикла;
    
    // Принудительно вызываем выгрузку удаления через стандартный серверный метод
    ОбменДаннымиXDTOСервер.ВыгрузитьУдаление(КомпонентыОбмена, ДанныеИБ.Ссылка);
КонецЕсли;

Обратите внимание: данный метод работает безупречно при условии, что идентификация (сопоставление) объектов в базе-приемнике настроена по уникальному идентификатору (GUID). Если сопоставление идет по полям поиска (например, по Коду или Наименованию), то команда удаления может не найти объект в приемнике.

Способ 2. Передача признака пометки на удаление через AdditionalInfo

Если сопоставление по GUID использовать нельзя, или вам требуется более гибкий контроль над объектом при его получении, можно использовать универсальный контейнер дополнительных свойств — узел AdditionalInfo. Большинство типов объектов в формате EnterpriseData содержат эту коллекцию, передающую произвольные пары «ключ-значение».

Реализуем этот механизм по шагам.

Шаг 1. Модификация ПКО на стороне базы-источника

В правилах конвертации объектов (ПКО) нужного справочника или документа найдем обработчик события ПриОтправкеДанных. Нам нужно внедрить значение свойства ПометкаУдаления в структуру AdditionalInfo:


// Проверяем наличие и инициализируем структуру AdditionalInfo в данных XDTO
Если Не ДанныеXDTO.Свойство("AdditionalInfo") Или ТипЗнч(ДанныеXDTO.AdditionalInfo) <> Тип("Структура") Тогда
    ДанныеXDTO.Вставить("AdditionalInfo", Новый Структура);
КонецЕсли;

// Записываем текущее состояние пометки удаления объекта базы данных
ДанныеXDTO.AdditionalInfo.Вставить("ПометкаУдаления", ДанныеИБ.ПометкаУдаления);

Шаг 2. Перехват свойства на стороне базы-приемника

Теперь переходим к базе-приемнику. В том же ПКО в обработчике события ПриКонвертацииДанныхXDTO извлекаем переданное значение и помещаем его во временные дополнительные свойства создаваемого или обновляемого объекта:


Если ДанныеXDTO.Свойство("AdditionalInfo") И ТипЗнч(ДанныеXDTO.AdditionalInfo) = Тип("Структура") Тогда
    ПометкаУдаления = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ДанныеXDTO.AdditionalInfo, "ПометкаУдаления", Ложь);
    Если ПометкаУдаления Тогда
        ПолученныеДанные.ДополнительныеСвойства.Вставить("ПометкаУдаления", Истина);
    КонецЕсли;
EndIf;

Шаг 3. Установка пометки перед записью в базу данных

Последний штрих — обработчик события ПередЗаписьюПолученныхДанных на стороне приемника. Здесь мы непосредственно управляем реквизитами записываемого объекта:


Если ПолученныеДанные.ДополнительныеСвойства.Свойство("ПометкаУдаления") Тогда
    ДанныеИБ.ПометкаУдаления = Истина;
КонецЕсли;

Этот способ крайне надежен, не нарушает структуру XDTO-пакета и позволяет корректно обновлять реквизиты объекта, сохраняя историю изменений в приемнике.

Способ 3. Создание расширения формата XDTO

Для крупных корпоративных систем, где обмен кастомизируется через конфигурацию «Конвертация данных 3.1», наиболее технологичным решением является расширение самого формата EnterpriseData.

Рассмотрим этот процесс концептуально:

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

Резюме

Мы проанализировали проблему непереноса объектов, помеченных на удаление, в универсальном формате обмена 1С. В зависимости от требований к интеграции вы можете выбрать наиболее подходящий путь:

← На главную