Почему не создается запись регистра сведений после загрузки объекта при синхронизации в 1С?

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

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

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

Выясняем причины: почему код работает в Универсальном обмене, но молчит при синхронизации?

Для начала давайте разберем типичный сценарий. Разработчик в ПКО справочника (например, способы отражения зарплаты) в обработчике После загрузки (или ошибочно названном «После обработки») пишет следующий код:


НаборЗаписей = РегистрыСведений.ПорядокОтраженияЗарплатыВБухУчете.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.СпособОтраженияЗарплатыВБухУчете.Установить(Объект.Ссылка);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.СпособОтраженияЗарплатыВБухУчете = Объект.Ссылка;
НаборЗаписей.Записать();

При ручном переносе через обработку «Универсальный обмен» этот код успешно отрабатывает. Но при синхронизации в фоновом режиме записи в регистре не появляются. Проанализируем ключевые причины этого сбоя.

  1. Не обновлены правила корреспондента в базе-приемнике. Это самая частая причина. При ручном обмене вы указываете файл правил непосредственно в обработке загрузки. В современных типовых конфигурациях на базе БСП правила обмена передаются не «на лету» внутри XML-файла с данными (это заблокировано из соображений безопасности). База-приемник использует свои локально сохраненные правила — так называемые правила корреспондента. Если вы обновили правила в источнике, но не загрузили их в базу-приемник через настройки синхронизации, ваш новый код на стороне приемника просто отсутствует.
  2. Объект еще физически не записан в базу данных. Обработчик После загрузки срабатывает в момент, когда объект прочитан из XML-файла и заполнен в памяти, но еще не сохранен в СУБД. В этот момент у нового объекта свойство Объект.Ссылка может быть еще пустым или не иметь фактической записи в таблице базы данных. Попытка записать набор записей регистра с незаписанной ссылкой приводит к ошибке целостности базы данных или созданию битых ссылок, из-за чего транзакция записи может тихо откатываться.
  3. Флаг загрузки данных (ОбменДанными.Загрузка = Истина). При работе встроенных механизмов БСП все транзакции по записи объектов жестко контролируются. Если при записи создаваемого вручную набора записей регистра сведений не выставить флаг ОбменДанными.Загрузка = Истина, система начнет выполнять всю сопутствующую бизнес-логику регистра (подписки на события, проверки в модуле набора записей). В режиме синхронизации это часто вызывает конфликты блокировок или транзакционные ошибки.
  4. Безопасный режим выполнения кода БСП. Синхронизация данных часто выполняется в безопасном режиме платформы. В этом режиме могут быть заблокированы прямые транзакционные вызовы к базе данных (такие как метод Записать() для созданных вручную наборов записей), если они выполняются в обход стандартных механизмов XML-десериализации.

Теперь, когда мы понимаем физику процесса, давайте пошагово разберем методы устранения проблемы.

Решение 1. Обновление правил корреспондента в базе-приемнике

Если ваша база-приемник работает на управляемых формах (например, Бухгалтерия предприятия 3.0), обязательно обновите правила обмена на обеих сторонах. Для этого выполним следующие действия:

  1. Выгрузите измененные правила из «Конвертации данных 2.1».
  2. Перейдите в базу-приемник в раздел Администрирование — Синхронизация данных.
  3. Откройте список настроек синхронизации, выберите нужное подключение и нажмите кнопку «Параметры синхронизации» — «Загрузить правила обмена» (в зависимости от версии БСП интерфейс может незначительно отличаться, ищите пункт «Правила обмена корреспондента»).
  4. Загрузите XML-файл правил непосредственно в приемник.

Решение 2. Корректировка программного кода и правильный выбор обработчика

Давайте оптимизируем код создания записи регистра сведений. Во-первых, перенесем код из обработчика После загрузки в обработчик После записи ПКО справочника. На данном этапе объект гарантированно записан в базу данных и имеет валидную ссылку.

Во-вторых, обязательно добавим установку флага ОбменДанными.Загрузка для создаваемого набора записей. Рассмотрим правильный пример написания кода:


// Код пишется в ПКО нужного справочника, в событии "После записи"
НаборЗаписей = РегистрыСведений.ПорядокОтраженияЗарплатыВБухУчете.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.СпособОтраженияЗарплатыВБухУчете.Установить(Объект.Ссылка);

НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.СпособОтраженияЗарплатыВБухУчете = Объект.Ссылка;
// Здесь можно заполнить другие реквизиты и измерения регистра, если необходимо

// Установка флага загрузки критически важна для обхода лишних проверок и исключения зацикливания обмена!
НаборЗаписей.ОбменДанными.Загрузка = Истина;

Попытка
    НаборЗаписей.Записать();
Исключение
    ЗаписьЖурналаРегистрации("ОбменДанными.ЗаписьРегистра",
        УровеньЖурналаРегистрации.Ошибка, , ,
        "Не удалось записать регистр для объекта: " + ОписаниеОшибки());
КонецПопытки;

Использование конструкции Попытка...Исключение с выводом информации в Журнал регистрации позволит вам быстро локализовать проблему, если запись регистра все же заблокируется из-за каких-либо внутренних ограничений базы данных.

Решение 3. Архитектурно правильный перенос (Рекомендуется)

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

Давайте разберем по шагам, как настроить автоматический перенос регистра сведений без написания кода записи в приемнике:

  1. В базе «Конвертация данных 2.1» создайте стандартное ПКО для регистра сведений ПорядокОтраженияЗарплатыВБухУчете. Настройте правила конвертации свойств (ПКС) для его измерений и ресурсов.
  2. Перейдите в ПКО исходного справочника (из которого нужно инициировать создание записи регистра).
  3. Откройте обработчик события «После выгрузки» (это событие выполняется на стороне базы-источника).
  4. Пропишите вызов выгрузки регистра по правилу с передачей объекта-источника в качестве параметра:

// Передаем ссылку на текущий справочник-источник в ПКО регистра сведений
ВыгрузитьПоПравилу(Источник, , , , "ПорядокОтраженияЗарплатыВБухУчете");

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

← На главную