Как передать пометку на удаление и статус проведения документа в Универсальном формате EnterpriseData?

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

При настройке обменов данными через Универсальный формат (EnterpriseData, Конвертация данных 3.0 и Библиотека Стандартных Подсистем) разработчики часто сталкиваются с нестандартным поведением документов: признак проведения по умолчанию в формате отсутствует, а попытка вручную установить пометку удаления в обработчиках загрузки вызывает исключительные ситуации. Разберем по шагам архитектуру обмена, выясним причины ошибок и рассмотрим штатные способы синхронизации статусов документов.

Почему возникает ошибка при вызове УстановитьПометкуУдаления

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

Объект.УстановитьПометкуУдаления(Истина);

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

  1. Метод УстановитьПометкуУдаления() является интерактивным серверным методом объекта, который немедленно инициирует транзакцию записи в информационную базу со сменой режима проведения.
  2. В подсистеме обмена БСП загрузка и проведение выполняются в рамках собственных управляемых транзакций и пакетных механизмов. Попытка неявной записи объекта внутри обработчика приводит к конфликтам блокировок данных и вложенных транзакций.

Для корректного изменения признака пометки удаления в обработчиках загрузки КД 3.0 необходимо напрямую менять реквизит и взводить флаг модификации:


Объект.ПометкаУдаления = Истина;
ОбъектМодифицирован = Истина;

Штатная концепция EnterpriseData: передача удаления объектов

В архитектуре формата EnterpriseData физическое удаление объекта и установка пометки на удаление не разделяются на уровне XML-сообщения. Механизм работает по следующим правилам:

  1. В исходящем сообщении формируется служебный узел <УдалениеОбъекта>, содержащий ключевые поля идентификации и ссылку на исходный объект.
  2. База-приемник при чтении узла <УдалениеОбъекта> не удаляет объект физически из базы, а находит его по идентификаторам, снимает с проведения и штатно устанавливает свойство ПометкаУдаления = Истина.
  3. Если в правилах регистрации объектов (ПРО) настроен отбор (например, регистрировать только проведенные документы), то при отмене проведения или установке пометки удаления в источнике платформа автоматически формирует запись удаления на узле плана обмена.

Посмотрим на код БСП, отвечающий за выборку и выгрузку удалений:


// Извлечение изменений на узле плана обмена
Данные = ВыборкаИзменений.Получить();

Если ТипЗнч(Данные) = Тип("УдалениеОбъекта") Тогда
    ВыгрузитьУдаление(КомпонентыОбмена, Данные.Ссылка);
Иначе
    // Штатная выгрузка заполненного объекта
    ВыгрузитьПоПравилу(Данные, КомпонентыОбмена, ПравилоОбработки);
КонецЕсли;

Как синхронизировать отмену проведения и непроведенные документы

Формат EnterpriseData спроектирован с упором на передачу фактических бизнес-данных, а не платформенных состояний. Статус проведения документа обрабатывается одним из двух архитектурных подходов:

  1. Регистрация только проведенных документов (типовой подход). В правилах регистрации настраивается условие выгрузки только документов со статусом Проведен = Истина. Если проведенный документ в базе-источнике распроводят или удаляют, механизм БСП автоматически фиксирует удаление объекта из выборки узла и отправляет в приемник пакет <УдалениеОбъекта>. В базе-приемнике документ автоматически распроводится и помечается на удаление.
  2. Использование дополнительных свойств (AdditionalInfo) и режима записи. Если в базе-приемнике необходимо хранить документ непроведенным (без пометки удаления), флаг состояния передается через дополнительную структуру в XML:

    В обработчике отправки источника:

    
    // Запись статуса в структуру дополнительных данных
    ДанныеXDTO.AdditionalInfo = Новый Структура("БылПроведен", Объект.Проведен);
    

    В обработчике ПередЗаписьюПолученныхДанных или ПриКонвертацииДанных на стороне приемника:

    
    Если Объект.ДополнительныеСвойства.Свойство("AdditionalInfo") 
        И Объект.ДополнительныеСвойства.AdditionalInfo.Свойство("БылПроведен") Тогда
        
        Если Не Объект.ДополнительныеСвойства.AdditionalInfo.БылПроведен Тогда
            // Указываем режим записи без проведения
            РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения;
        КонецЕсли;
    КонецЕсли;
    

Особенность БСП при наличии нескольких ПКО для одного объекта

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


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

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

← На главную