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

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

При настройке обмена данными между конфигурациями 1С (например, из ЗУП 2.5 в Розницу 2.2) с использованием механизма Конвертации данных 2.1 разработчики часто сталкиваются с ситуацией, когда обмен через файл работает безупречно, а при переходе на COM-соединение часть алгоритмов в обработчиках ПКО (Правил конвертации объектов) перестает выполняться. Типичный пример — создание связанных объектов, таких как дисконтные карты или записи в регистрах сведений (штрихкоды), непосредственно в обработчике После загрузки.

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

Проанализируем ситуацию: файл против COM-соединения

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

При использовании COM-соединения (внешнего соединения) база-источник подключается к базе-приемнику программно. Весь код обработчиков загрузки выполняется в специальном сеансе — сеансе внешнего соединения. Рассмотрим основные причины, по которым код может «молча» игнорироваться или вызывать ошибки в этом режиме.

Причина 1: Механизм обновления правил в конфигурациях на базе БСП

Проанализируем, как Розница 2.2 (и другие конфигурации на БСП) работает с правилами обмена. В современных конфигурациях правила часто хранятся внутри самой информационной базы. Даже если вы подключаетесь из ЗУП 2.5 и указываете локальный файл правил, система при COM-соединении может использовать так называемые правила конфигурации корреспондента (CorrespondentExchangeRules.XML), которые уже загружены в базу-приемник.

Если вы внесли изменения в обработчик После загрузки в файл правил на стороне источника, но не обновили правила в самой Рознице (в регистре сведений «Правила обмена данными» или в настройках узла обмена), то при COM-запросе приемник выполнит старую версию кода, где вашего алгоритма создания штрихкода просто нет.

Решение: Обязательно загрузите обновленные правила обмена в базу-приемник. Убедитесь, что в настройках синхронизации данных в Рознице 2.2 используются именно актуальные правила.

Причина 2: Проблема записи объекта и получения ссылки

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

Посмотрим на пример кода, который может вызвать проблему:


// Создаем новый штрихкод
ЗаписьШтрихкода = РегистрыСведений.Штрихкоды.СоздатьМенеджерЗаписи;
ЗаписьШтрихкода.Владелец = НоваяКарта.Ссылка;
ЗаписьШтрихкода.ТипШтрихкода = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN13;
ЗаписьШтрихкода.Штрихкод = ИмяКарты;
Попытка
    ЗаписьШтрихкода.Записать;
Исключение
    // Ошибка может быть подавлена во внешнем соединении
КонецПопытки;

Если НоваяКарта была только что создана, перед созданием записи в регистре сведений необходимо убедиться, что карта физически записана. Кроме того, в режиме COM-соединения рекомендуется явно вызывать Объект.Записать(), если вы планируете использовать _Ссылка (ссылку на загружаемый объект) для связи с другими данными.

Причина 3: Контекст внешнего соединения и доступность модулей

Выясним причину, связанную с программной средой. Внешнее соединение имеет ряд ограничений:

  1. Общие модули: Если ваш код в обработчике вызывает процедуры из общих модулей, у этих модулей в конфигураторе должен стоять флаг «Внешнее соединение». Если флаг не установлен, система выдаст ошибку «Метод не обнаружен», которую вы не увидите в интерфейсе источника.
  2. Интерактивные действия: Любые попытки вызвать Предупреждение(), Вопрос() или методы, помеченные директивой &НаКлиенте, приведут к немедленному прерыванию выполнения кода.
  3. Вывод сообщений: Метод Сообщить() во внешнем соединении часто уходит «в никуда». Для отладки используйте ЗаписьЖурналаРегистрации().

Причина 4: Использование Менеджера Записи vs Набор Записей

Для регистров сведений в 1С существует два способа записи: МенеджерЗаписи и НаборЗаписей. Практика показывает, что при работе через COM-соединение использование СоздатьМенеджерЗаписи() может быть менее стабильным из-за особенностей блокировок в транзакции. Рассмотрим более надежный вариант с использованием набора записей:


НаборШтрихкодов = РегистрыСведений.Штрихкоды.СоздатьНаборЗаписей();
НаборШтрихкодов.Отбор.Владелец.Установить(НоваяКарта.Ссылка);
НаборШтрихкодов.Отбор.Штрихкод.Установить(ИмяКарты);

НоваяЗапись = НаборШтрихкодов.Добавить();
НоваяЗапись.Владелец = НоваяКарта.Ссылка;
НоваяЗапись.Штрихкод = ИмяКарты;
НоваяЗапись.ТипШтрихкода = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN13;

НаборШтрихкодов.ОбменДанными.Загрузка = Истина;
НаборШтрихкодов.Записать();

Обратите внимание на использование свойства ОбменДанными.Загрузка = Истина. Это отключает лишние проверки в модуле набора записей, что критически важно при автоматическом создании данных во время обмена.

Как отладить COM-соединение?

Поскольку стандартная отладка не заходит в код приемника при COM-обмене, выполним следующие шаги для поиска ошибки:

  1. Запустите конфигуратор базы-приемника.
  2. Перейдите в меню Отладка -> Подключение.
  3. В открывшемся окне нажмите кнопку Настройка и убедитесь, что установлен флаг «Внешние соединения».
  4. После этого в списке доступных предметов отладки появится сеанс внешнего соединения, созданный базой-источником. Подключитесь к нему.
  5. Теперь вы можете ставить точки останова в правилах обмена (в модуле обработки загрузки или в общих модулях) и анализировать значения переменных в реальном времени.

Рекомендуемый алгоритм в обработчике «После загрузки»

Подведем итог и составим правильную структуру кода для создания зависимых объектов:


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

// 2. Логика создания дисконтной карты
// Используем переменную _Ссылка, так как это ссылка на текущий загруженный объект
ИмяКарты = Объект.ИдентификационныйКодЛичности; 
КартаСотрудника = Справочники.ИнформационныеКарты.НайтиПоНаименованию(ИмяКарты);

Если КартаСотрудника.Пустая() Тогда
    НоваяКарта = Справочники.ИнформационныеКарты.СоздатьЭлемент();
    НоваяКарта.Наименование = СокрЛП(ИмяКарты);
    НоваяКарта.ВладелецКарты = Объект.Ссылка;
    // ... заполнение остальных реквизитов ...
    
    Попытка
        НоваяКарта.ОбменДанными.Загрузка = Истина;
        НоваяКарта.Записать();
        
        // 3. Создание штрихкода через НаборЗаписей
        Набор = РегистрыСведений.Штрихкоды.СоздатьНаборЗаписей();
        Набор.Отбор.Владелец.Установить(НоваяКарта.Ссылка);
        
        НоваяЗапись = Набор.Добавить();
        НоваяЗапись.Владелец = НоваяКарта.Ссылка;
        НоваяЗапись.Штрихкод = ИмяКарты;
        НоваяЗапись.ТипШтрихкода = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN13;
        
        Набор.Записать();
        
    Исключение
        ЗаписьЖурналаРегистрации("Обмен_Данными", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка создания карты: " + ОписаниеОшибки());
    КонецПопытки;
КонецЕсли;

Используя такой подход, вы минимизируете риски возникновения «невидимых» ошибок и обеспечите стабильную работу обмена данными как через файлы, так и через COM-соединение.

← На главную