При настройке правил обмена в конфигурации «1С:Конвертация данных 2.0» стандартное поведение обработчиков загрузки заключается в полной перезаписи реквизитов объекта-приемника значениями из файла обмена. Однако часто возникает задача не заменять данные, а дополнять их — например, дописывать новые идентификаторы, штрихкоды или коды через точку с запятой (было 001, пришло 002, в результате должно стать 001; 002).
Разберем подробно, на каком этапе загрузки перехватить данные, как правильно обратиться к текущему состоянию объекта в базе данных и как избежать дублирования информации.
Для модификации загружаемых данных перед их окончательной записью в информационную базу используется событие «После загрузки» в Правиле конвертации объекта (ПКО).
В этом событии разработчику доступны следующие ключевые переменные:
Объект — ссылка на сформированный в оперативной памяти объект информационной базы (например, СправочникОбъект), реквизиты которого уже заполнены данными из входящего файла XML, но еще не записаны в базу.Ссылка — ссылка на найденный объект в базе данных приемника.ОбъектНайден — булевый флаг, указывающий, был ли объект найден по полям поиска (Истина) или создается новый элемент (Ложь).Важное замечание: переменная Объект уже представляет собой объектную сущность, поэтому попытка вызвать конструкцию Объект.ПолучитьОбъект() приведет к синтаксической ошибке. Старое значение из базы данных нужно считывать через ссылку — Ссылка.ИмяРеквизита.
Рассмотрим базовый сценарий. Создано стандартное Правило конвертации свойства (ПКС), которое заполняет реквизит новым значением. В обработчике «После загрузки» ПКО мы проверяем, существовал ли объект в базе, получаем старое значение реквизита и склеиваем его с новым.
Посмотрим на пример кода с проверкой заполненности и корректной расстановкой разделителей:
Если ОбъектНайден Тогда
// Получаем текущее значение из базы данных приемника
СтароеЗначение = Ссылка.Коды;
НовоеЗначение = Объект.Коды;
Если ЗначениеЗаполнено(СтароеЗначение) Тогда
// Проверяем, не было ли значение уже добавлено ранее
Если СтрНайти(СтароеЗначение, НовоеЗначение) = 0 Тогда
Объект.Коды = СокрЛП(СтароеЗначение) + "; " + СокрЛП(НовоеЗначение);
Иначе
// Если код уже присутствует в строке, оставляем старое значение
Объект.Коды = СтароеЗначение;
КонецЕсли;
Иначе
Объект.Коды = НовоеЗначение;
КонецЕсли;
КонецЕсли;
Чтобы избежать двойной перезаписи реквизита (сначала при разборе XML в ПКС, а затем в обработчике ПКО), можно передать добавляемое значение через дополнительный параметр объекта.
Разберем этот способ по шагам:
ПараметрыОбъекта.Вставить("ДобавляемыйКод", Источник.Код);
Если ПараметрыОбъекта <> Неопределено И ПараметрыОбъекта.Свойство("ДобавляемыйКод") Тогда
Добавляемое = СокрЛП(ПараметрыОбъекта["ДобавляемыйКод"]);
Если ЗначениеЗаполнено(Добавляемое) Тогда
Если ОбъектНайден Тогда
ТекущееЗначение = СокрЛП(Ссылка.Коды);
Если ЗначениеЗаполнено(ТекущееЗначение) Тогда
Если СтрНайти(ТекущееЗначение, Добавляемое) = 0 Тогда
Объект.Коды = ТекущееЗначение + "; " + Добавляемое;
КонецЕсли;
Иначе
Объект.Коды = Добавляемое;
КонецЕсли;
Иначе
Объект.Коды = Добавляемое;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Строка(50)), многократная конкатенация приведет к превышению лимита символов и автоматической обрезке данных при записи. Убедитесь, что реквизит имеет неограниченную длину либо контролируйте размер через функцию СтрДлина().СтрНайти() или разбиение на массив через СтрРазделить()), иначе при перезагрузке файла обмена данные продублируются (001; 002; 002).ОбъектНайден = Ложь, обращение к Ссылка.ИмяРеквизита вернет пустое значение, так как объект создается в базе впервые.