Почему в Конвертации данных 2.1 не работает флаг «Не замещать существующие объекты» и как это исправить?

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

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

Анализ проблемы: почему стандартные механизмы дают сбой

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

Даже если мы попытаемся переопределить логику в обработчиках событий правила:


// Обработчик "При загрузке"
Если ОбъектНайден Тогда
    НеЗамещатьОбъект = Истина;
КонецЕсли;

// Обработчик "После загрузки"
Если ОбъектНайден Тогда
    Отказ = Истина;
КонецЕсли;

Элемент все равно может быть перезаписан. Выясним причину такого поведения в механизмах загрузки данных КД 2.1:

  1. Ошибка совместного поиска по GUID и полям поиска: В коде типовой обработки загрузки данных содержится баг. Если при поиске по внутреннему идентификатору объект не найден, но алгоритм успешно находит его на следующем шаге по полям поиска, служебная переменная ОбъектНайден ошибочно остается равной Ложь. При этом ссылка на существующий объект в переменной СсылкаНаОбъект уже получена и заполнена. В результате условие Если ОбъектНайден Тогда попросту не выполняется, а механизм считает объект новым и принудительно перезаписывает его свойства.
  2. Особенности обработчика «Поля поиска»: В некоторых релизах КД 2.1 (например, 2.1.7.1) наличие любого текста или даже комментариев в обработчике «Поля поиска» приводит к принудительному обновлению свойств найденного объекта, полностью игнорируя флаги «Не замещать» на уровне ПКО и ПКС.
  3. Неверная область видимости параметра «Отказ»: Обратите внимание, что для платформы 1С:Предприятие в обработчике «При загрузке» параметра Отказ нет. Попытка установить Отказ = Истина в этом обработчике не возымеет эффекта. За отмену модификации здесь отвечает исключительно параметр НеЗамещатьОбъект = Истина. Параметр Отказ доступен позже — в обработчике «После загрузки».
  4. Ограничения on-line обмена: В справке КД не случайно указано предупреждение о нежелательности использования флага при постоянном обмене по планам обмена. Запрет замещения при двусторонней синхронизации приводит к постоянной коллизии: объект в приемнике не меняется, регистрация изменений на узлах может не очищаться, что вызывает бесконечную передачу одних и тех же данных.

Способ 1. Проверка заполненности ссылки в обработчике «При загрузке»

Поскольку ошибка алгоритма приводит к сбросу флага ОбъектНайден, но при этом переменная СсылкаНаОбъект содержит валидную ссылку на найденный в базе элемент, мы можем обойти проблему прямой проверкой ссылки.

Откроем ПКО нужного справочника или документа, перейдем в обработчик «При загрузке» и напишем следующий код:


Если ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
    НеЗамещатьОбъект = Истина;
КонецЕсли;

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

Способ 2. Отмена записи через проверку на новый объект в «После загрузки»

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

Для проверки факта того, что объект уже существовал в информационной базе до момента начала загрузки, проверим метод объекта ЭтоНовый():


Если Не Объект.ЭтоНовый() Тогда
    Отказ = Истина;
КонецЕсли;

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

Способ 3. Корректировка стратегии поиска и отключение поиска по GUID

Если для конкретного правила синхронизации ключевыми являются именно реквизиты поиска (например, Код, ИНН, Наименование), проанализируем настройки вкладки поиска в ПКО:

  1. Снимем флаг «Искать по внутреннему идентификатору».
  2. Оставим активными флаги поиска исключительно у ключевых свойств в таблице ПКС.

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

Способ 4. Явное управление в обработчике «Поля поиска»

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


// Пример программного поиска по коду
НайденнаяСсылка = Справочники.Номенклатура.НайтиПоКоду(СвойстваПоиска["Код"]);

Если ЗначениеЗаполнено(НайденнаяСсылка) Тогда
    СсылкаНаОбъект = НайденнаяСсылка;
    ПрекратитьПоиск = Истина;
КонецЕсли;

Установка флага ПрекратитьПоиск = Истина сообщает механизму загрузки, что объект успешно сопоставлен, и предотвращает дальнейшие сбойные проверки по идентификаторам.

← На главную