Как в Конвертации данных 2.0 добавить значение к свойству приемника вместо перезаписи

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

При настройке правил обмена в конфигурации «1С:Конвертация данных 2.0» стандартное поведение обработчиков загрузки заключается в полной перезаписи реквизитов объекта-приемника значениями из файла обмена. Однако часто возникает задача не заменять данные, а дополнять их — например, дописывать новые идентификаторы, штрихкоды или коды через точку с запятой (было 001, пришло 002, в результате должно стать 001; 002).

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

Анализ контекста обработчиков в КД 2.0

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

В этом событии разработчику доступны следующие ключевые переменные:

  1. Объект — ссылка на сформированный в оперативной памяти объект информационной базы (например, СправочникОбъект), реквизиты которого уже заполнены данными из входящего файла XML, но еще не записаны в базу.
  2. Ссылка — ссылка на найденный объект в базе данных приемника.
  3. ОбъектНайден — булевый флаг, указывающий, был ли объект найден по полям поиска (Истина) или создается новый элемент (Ложь).

Важное замечание: переменная Объект уже представляет собой объектную сущность, поэтому попытка вызвать конструкцию Объект.ПолучитьОбъект() приведет к синтаксической ошибке. Старое значение из базы данных нужно считывать через ссылку — Ссылка.ИмяРеквизита.

Решение 1. Обработка через событие «После загрузки» (ПКО)

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

Посмотрим на пример кода с проверкой заполненности и корректной расстановкой разделителей:


Если ОбъектНайден Тогда
    // Получаем текущее значение из базы данных приемника
    СтароеЗначение = Ссылка.Коды;
    НовоеЗначение  = Объект.Коды;
    
    Если ЗначениеЗаполнено(СтароеЗначение) Тогда
        // Проверяем, не было ли значение уже добавлено ранее
        Если СтрНайти(СтароеЗначение, НовоеЗначение) = 0 Тогда
            Объект.Коды = СокрЛП(СтароеЗначение) + "; " + СокрЛП(НовоеЗначение);
        Иначе
            // Если код уже присутствует в строке, оставляем старое значение
            Объект.Коды = СтароеЗначение;
        КонецЕсли;
    Иначе
        Объект.Коды = НовоеЗначение;
    КонецЕсли;
КонецЕсли;

Решение 2. Передача значения через «ПараметрыОбъекта» без создания ПКС

Чтобы избежать двойной перезаписи реквизита (сначала при разборе XML в ПКС, а затем в обработчике ПКО), можно передать добавляемое значение через дополнительный параметр объекта.

Разберем этот способ по шагам:

  1. В конфигурации источника в ПКО в событии «После выгрузки» помещаем значение в коллекцию параметров: ПараметрыОбъекта.Вставить("ДобавляемыйКод", Источник.Код);
  2. В ПКС для данного реквизита правило не создаем либо отключаем его.
  3. В конфигурации приемника в ПКО в событии «После загрузки» получаем параметр и дополняем реквизит:
    
    Если ПараметрыОбъекта <> Неопределено И ПараметрыОбъекта.Свойство("ДобавляемыйКод") Тогда
        Добавляемое = СокрЛП(ПараметрыОбъекта["ДобавляемыйКод"]);
        
        Если ЗначениеЗаполнено(Добавляемое) Тогда
            Если ОбъектНайден Тогда
                ТекущееЗначение = СокрЛП(Ссылка.Коды);
                
                Если ЗначениеЗаполнено(ТекущееЗначение) Тогда
                    Если СтрНайти(ТекущееЗначение, Добавляемое) = 0 Тогда
                        Объект.Коды = ТекущееЗначение + "; " + Добавляемое;
                    КонецЕсли;
                Иначе
                    Объект.Коды = Добавляемое;
                КонецЕсли;
            Иначе
                Объект.Коды = Добавляемое;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
    

Важные технические ограничения и рекомендации

  1. Длина строкового реквизита: если реквизит в приемнике имеет ограниченную длину (например, Строка(50)), многократная конкатенация приведет к превышению лимита символов и автоматической обрезке данных при записи. Убедитесь, что реквизит имеет неограниченную длину либо контролируйте размер через функцию СтрДлина().
  2. Повторная загрузка одного файла: обязательно проверяйте наличие добавляемой подстроки в существующей строке (через СтрНайти() или разбиение на массив через СтрРазделить()), иначе при перезагрузке файла обмена данные продублируются (001; 002; 002).
  3. Новые объекты: если ОбъектНайден = Ложь, обращение к Ссылка.ИмяРеквизита вернет пустое значение, так как объект создается в базе впервые.
← На главную