Почему обработчик После загрузки данных в Конвертации данных 2.1 не работает при синхронизации

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

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

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

Различия в механизмах выполнения: Универсальная обработка vs БСП

Первое, что нам необходимо проанализировать — это среда выполнения кода. Когда мы используем Универсальный обмен данными XML, весь процесс происходит в рамках одного сеанса, в интерактивном режиме (часто на клиенте или в явном вызове на сервере). Штатная синхронизация в современных конфигурациях (УТ 11, КА 2, ERP) базируется на Библиотеке стандартных подсистем (БСП) и имеет ряд особенностей:

  1. Фоновые задания: Синхронизация запускается как фоновое задание. Любые попытки вызвать диалоговые окна, сообщения Сообщить() или Предупреждение() будут проигнорированы или приведут к ошибке, которая не отобразится в интерфейсе.
  2. Безопасный режим: БСП часто исполняет код правил в безопасном режиме. Если ваши правила загружены как внешние, выполнение произвольного кода может быть ограничено профилями безопасности.
  3. Кэширование правил: Изменения в правилах могут не подхватываться сразу. БСП хранит правила в специальном регистре сведений (например, ПравилаДляОбменаДанными). Пока вы принудительно не обновите правила в узле обмена, система будет использовать старую версию кода.
  4. Транзакционность и пакеты: В штатной синхронизации данные могут загружаться пакетами. Глобальные параметры, инициализированные в начале, могут вести себя непредсказуемо, если сеанс загрузки прерывается или разделяется.

Проблема использования глобального массива в параметрах

Проанализируем алгоритм, предложенный автором: создание массива в Перед загрузкой данных, наполнение его в После загрузки ПКО и итоговая обработка в После загрузки данных конвертации. В теории это логично, но на практике в режиме синхронизации глобальный обработчик После загрузки данных может не вызываться или вызываться в момент, когда контекст параметров уже потерян (особенно при обмене через COM или веб-сервисы).

Решение 1: Перенос логики в ПКО (Прямое создание)

Самый надежный способ — отказаться от накопления списка объектов и выполнять создание зависимого документа сразу в обработчике После загрузки конкретного ПКО. Рассмотрим пример кода, который можно разместить непосредственно в ПКО Поступления товаров и услуг:


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

Такой подход гарантирует, что действие произойдет мгновенно после успешной загрузки основного объекта, вне зависимости от того, как БСП управляет сессией загрузки данных.

Решение 2: Использование общих модулей для стабильности и отладки

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

Шаги реализации:

  1. Создадим в конфигурации КА (приемник) серверный общий модуль, например, ДоработкиОбменаСервер.
  2. В модуле напишем экспортную процедуру:

Процедура СоздатьДокументНаОснованииПоступления(СсылкаНаПоступление) Экспорт
    // Логика создания документа
    // Здесь можно ставить точки останова
    ЗаписьЖурналаРегистрации("ОбменДанными.СозданиеДокумента", 
        УровеньЖурналаРегистрации.Информация, , , 
        "Обработка документа: " + СсылкаНаПоступление);
    // ... код создания ...
КонецПроцедуры
  1. В Конвертации данных, в обработчике ПКО После загрузки, вызываем эту процедуру:

Если НЕ Отказ Тогда
    ДоработкиОбменаСервер.СоздатьДокументНаОснованииПоступления(Объект.Ссылка);
КонецЕсли;

Важно: Чтобы этот код сработал, общий модуль должен иметь флаги «Сервер», «Вызов сервера». Если обмен идет в безопасном режиме, убедитесь, что вызов этого модуля разрешен.

Решение 3: Проверка регистрации правил и типа обмена

Выясним причину, почему код может игнорироваться. В БСП правила загружаются отдельно для отправителя и для получателя. Вы должны убедиться, что измененные правила загружены именно в базу-приемник (КА) в настройку «Правила загрузки данных» или «Корреспондентские правила».

Разберем, как проверить работу кода без отладчика, если фоновое задание «проглатывает» ошибки:

Используйте ЗаписьЖурналаРегистрации. Это единственный надежный способ «увидеть» выполнение кода в фоне. Добавьте в начало обработчика После загрузки данных следующую строку:


ЗаписьЖурналаРегистрации("ОтладкаКД", УровеньЖурналаРегистрации.Информация, , , "Обработчик 'После загрузки данных' запущен. Кол-во элементов: " + Параметры.СписокПриобретений.Количество());

Если после выполнения синхронизации в Журнале Регистрации нет записи с тегом «ОтладкаКД», значит, либо правила не обновились в базе, либо глобальный обработчик вообще не вызывается в данном режиме обмена БСП.

Почему Ссылка может быть лучше чем Объект.Ссылка?

В некоторых версиях КД и при определенных настройках ПКО (например, если стоит флаг «Не замещать существующие объекты»), переменная Объект может содержать не совсем то, что вы ожидаете. Попробуйте использовать переменную Ссылка, которая в обработчике После загрузки гарантированно содержит ссылку на объект в БД.


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

Резюме

Для решения проблемы, когда обработчик не срабатывает при штатной синхронизации, мы рекомендуем:

← На главную