Как отказаться от записи объекта в базе-приемнике при обмене через Конвертацию данных 3.0?

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

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

В предыдущей версии конфигурации (Конвертация данных 2.0) эта задача решалась тривиально — достаточно было прописать Отказ = Истина в одном из обработчиков событий. В Конвертации данных 3.0, которая тесно интегрирована с Библиотекой стандартных подсистем (БСП), механизмы работы изменились. Попытки решить задачу «по старинке» часто приводят к тому, что код «не взлетает», либо система выдает ошибки в процессе обмена.

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

Почему не работает простая очистка полученных данных?

Рассмотрим типичную ошибку, которую часто совершают программисты. В правиле конвертации объектов (ПКО), в обработчике ПередЗаписьюПолученныхДанных, пишется следующий код:


Если ДанныеИБ <> Неопределено Тогда
     Зн = Обмен_Сервер.ПолучитьНеУчаствуетВОбмене(ДанныеИБ.Ссылка);
     Если Зн = Истина Тогда
         ПолученныеДанные = Неопределено;
         Возврат;
     КонецЕсли;
КонецЕсли;

Выясним причину, почему этот код не решает задачу корректно:

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

Давайте разберем правильные и рабочие варианты решения этой задачи. Перед выполнением массовых операций в базах данных и отладкой правил полезно запустить автоматическое создание резервных копий и архивирование баз 1С.

Вариант 1. Корректный отказ через «Перед записью полученных данных»

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


Если Обмен_Сервер.ПолучитьНеУчаствуетВОбмене(ДанныеИБ.Ссылка) Тогда
    ПолученныеДанные = Неопределено;
    ДанныеИБ = Неопределено;
    Возврат;
КонецЕсли;

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

Этот способ идеален, если решение об отказе от записи нужно принять на основе анализа состояния уже существующего в базе объекта (например, проверки его реквизитов в ИБ).

Вариант 2. Отказ от загрузки на этапе Правил обработки данных (ПОД)

Если решение об отказе можно принять еще на этапе разбора входящего пакета данных (до того, как система начнет искать объект в базе данных и сопоставлять ссылки), правильнее использовать механизмы Правил обработки данных (ПОД).

В Конвертации данных 3.0 для каждого ПОД существует обработчик события При обработке. В этом событии нам доступен параметр-структура ИспользованиеПКО. Мы можем программно управлять тем, какие правила конвертации объектов будут применяться для входящих данных.

Рассмотрим пример программного отключения загрузки конкретного документа:


// Пример логики в обработчике ПОД "При обработке"
Если ДанныеXDTO.ИмяТипа() = "Документ.РеализацияТоваровУслуг" Тогда
    // Проверяем условие, например, по значению реквизита из XML/XDTO
    Если ДанныеXDTO.Склад.Код = "ОСНОВНОЙ_ПРОДАЖИ" Тогда
        // Отключаем правило конвертации для данного объекта
        ИспользованиеПКО.Документ_РеализацияТоваровУслуг = Ложь;
    КонецЕсли;
КонецЕсли;

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

Вариант 3. Использование обработчика «При конвертации данных XDTO»

Еще один элегантный способ отсечь ненужные данные до начала поиска в ИБ — использовать обработчик ПКО При конвертации данных XDTO.

Здесь мы оперируем входящими XML-данными через объект ДанныеXDTO. Если по результатам анализа структуры XDTO мы понимаем, что объект нам не подходит, мы можем прервать конвертацию:


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

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

Важные нюансы, о которых нужно помнить

При реализации логики отказа от записи объектов обязательно учитывайте два важных архитектурных аспекта БСП:

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