Как в Конвертации данных 2.1 запретить изменение реквизита, если объект уже найден в базе-приемнике?

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

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

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

Способ 1. Использование стандартного флага в ПКС (самый оптимальный)

Самый простой и эффективный способ, предусмотренный разработчиками КД 2.1, находится непосредственно в настройках Правил конвертации свойств (ПКС). Рассмотрим ситуацию на примере реквизита Наименование.

Для того чтобы значение не обновлялось у существующих объектов, выполним следующие шаги:

  1. Откроем необходимое ПКО (Правило конвертации объекта).
  2. Перейдем в список ПКС.
  3. Найдем строку с реквизитом Наименование.
  4. Установим флаг «Не замещать значение свойства у существующих объектов в приемнике».

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

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

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

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

В ПКО (Правила конвертации объекта) в событии После загрузки на стороне приемника можно прописать следующий код:


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

Давайте разберем, что здесь происходит:

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

Способ 3. Программный отказ в ПКС (Событие «Перед загрузкой»)

Существует более «элегантный» программный способ, который позволяет отменить загрузку конкретного свойства еще до того, как оно будет присвоено объекту. Это делается в обработчике «Перед загрузкой» конкретного ПКС.

Рассмотрим пример кода в обработчике ПКС для реквизита Наименование:


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

Использование переменной Отказ = Истина в контексте ПКС говорит системе: «Пропусти загрузку именно этого реквизита для данного объекта». Это гибкий аналог стандартной галочки, который позволяет добавить дополнительные условия (например, не замещать, только если в источнике значение пустое или если объект относится к определенной группе).

Способ 4. Использование «Дополнительных свойств» для анализа

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

  1. В событии При загрузке (ПКО) сохраняем старое значение:
    
    Объект.ДополнительныеСвойства.Вставить("СтароеНаименование", Объект.Ссылка.Наименование);
    
  2. В событии После загрузки (ПКО) анализируем его:
    
    СтароеИмя = "";
    Если Объект.ДополнительныеСвойства.Свойство("СтароеНаименование", СтароеИмя) Тогда
         Если ЗначениеЗаполнено(СтароеИмя) И СтароеИмя <> Объект.Наименование Тогда
             // Ваша логика, например, восстановление или запись в лог
             Объект.Наименование = СтароеИмя;
         КонецЕсли;
    КонецЕсли;
    

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

Сравнение методов и влияние на производительность

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

Стандартный флаг ПКС: Выполняется платформенным кодом загрузчика, работает максимально быстро.

Код в обработчиках: Выполняется интерпретатором 1С. Каждый вызов Объект.Ссылка.Реквизит порождает отдельный SQL-запрос к базе данных. Если у вас 10 000 объектов, это 10 000 лишних запросов, что может существенно замедлить процесс обмена.

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

← На главную