Почему при загрузке через "Универсальный обмен данными" происходит регистрация изменений, если авторегистрация отключена?

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

При настройке обменов данными между базами 1С часто возникает ситуация, которая кажется парадоксальной: мы загружаем документы, явно отключаем для них авторегистрацию в плане обмена, проверяем, что загрузка идет в режиме ОбменДанными.Загрузка = Истина, но система все равно регистрирует эти документы как измененные для последующей выгрузки. Давайте разберем эту проблему подробно, проанализируем причины такого поведения и рассмотрим методы отладки, которые помогут найти "виновника".

Суть проблемы: когда настройки не работают

Рассмотрим типичный сценарий. Вы используете обработку "Универсальный обмен данными в формате XML" (или стандартные механизмы обмена БСП) для загрузки пакета документов. В метаданных Плана обмена для этого вида документа свойство Авторегистрация установлено в значение Запретить.

Логика подсказывает, что при записи документа в базу он не должен попадать в таблицу регистрации изменений. Более того, при загрузке данных свойство ОбменДанными.Загрузка устанавливается в значение Истина. Это платформенный флаг, который говорит системе: "Это не создание нового документа пользователем, это перенос данных, не нужно запускать лишние проверки и регистрации".

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

Где искать причину: стандартные и нестандартные механизмы

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

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

Как выяснилось в ходе разбора ситуации, наиболее коварным является третий пункт — подписки на события.

Эффективный метод поиска: Замер производительности

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

В таких случаях самым действенным инструментом является Замер производительности. Давайте рассмотрим алгоритм действий:

  1. Откройте конфигуратор и запустите сеанс отладки.
  2. В режиме "Предприятие" подготовьте обработку "Универсальный обмен" к загрузке файла.
  3. В конфигураторе включите "Замер производительности" (меню Отладка - Замер производительности).
  4. Нажмите кнопку "Загрузить" в обработке.
  5. Сразу после окончания загрузки отключите замер в конфигураторе.

Система выдаст таблицу всех выполненных строк кода. В строке поиска (Ctrl+F) наберите ключевое слово ЗарегистрироватьИзменения. Это позволит вам мгновенно найти тот участок кода, который фактически выполнил запись в таблицу регистрации, даже если он находится в неочевидном месте.

Главный "виновник": Подписки на все документы

В анализируемой нами ситуации причиной оказалась неочевидная подписка на события. В конфигурациях часто создают подписки, где в качестве источника (Тип источника) выбирают не конкретный документ (например, ДокументОбъект.РеализацияТоваровУслуг), а общий тип — ДокументОбъект.

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


// ОШИБОЧНЫЙ КОД в подписке на событие
Процедура ПриЗаписиВсехДокументов(Источник, Отказ) Экспорт
    // Здесь разработчик хочет зарегистрировать документ для выгрузки в какую-то внешнюю систему
    ПланыОбмена.ЗарегистрироватьИзменения(ПланыОбмена.МойОбмен.НайтиПоКоду("001"), Источник);
КонецПроцедуры

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

Как исправить и предотвратить ошибку

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

Правильный код должен выглядеть так:


Процедура ПриЗаписиВсехДокументов(Источник, Отказ) Экспорт
    
    // Если документ загружается из другой базы, прерываем выполнение
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

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

КонецПроцедуры

Дополнительные факторы, влияющие на регистрацию

Помимо описанной выше причины с подписками, давайте рассмотрим еще несколько нюансов, которые могут приводить к неожиданной регистрации изменений при использовании универсального обмена.

1. Код внутри правил обмена (КД 2.0)

Обработка "Универсальный обмен данными" выполняет правила конвертации, написанные в конфигурации "Конвертация данных 2.0". Внутри xml-файла правил могут содержаться обработчики событий на языке 1С, например ПослеЗагрузки (AfterLoad). Разработчик правил мог явно прописать там регистрацию:


// Пример кода внутри правил обмена (обработчик "ПослеЗагрузки")
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Объект);

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

2. Регистрация движений (наборов записей)

Важно помнить, что план обмена может регистрировать не только сам документ, но и его движения (записи регистров). Если в правилах обмена стоит флаг "Проводить документ при загрузке", то система запишет наборы записей регистров.

Если для регистров включена авторегистрация, то изменение набора записей вызовет регистрацию этого изменения. А в некоторых конфигурациях (особенно на базе БСП) существует логика: "Если изменился регистр, зарегистрируй к обмену и документ-регистратор". Это делается для того, чтобы поддержать целостность данных в базе-приемнике.

Резюме

Если вы столкнулись с "мистической" регистрацией объектов при загрузке:

  1. Убедитесь, что в метаданных Авторегистрация отключена.
  2. Используйте Замер производительности — это самый быстрый способ найти конкретную строчку кода, вызывающую метод ЗарегистрироватьИзменения.
  3. В первую очередь проверяйте Подписки на события, у которых в качестве источника указан базовый тип ДокументОбъект без уточнения вида документа.
  4. Всегда добавляйте проверку Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; в свои подписки, чтобы не ломать механизмы обмена.
← На главную