При настройке правил обмена в конфигурации «Конвертация данных 2.0» (КД 2.0) разработчики часто сталкиваются с задачей: необходимо перенести данные из двух разных табличных частей документа-источника (например, Услуги и Товары) в единую табличную часть документа-приёмника (например, ТоварыУслуги).
Если создать два отдельных Правила конвертации группы свойств (ПКГС) вида ТЧ1 -> ТЧ и ТЧ2 -> ТЧ, результат окажется неудовлетворительным. Разберёмся, почему это происходит и как правильно решить данную задачу.
Проанализируем алгоритм загрузки данных в КД 2.0. При обработке группы свойств табличной части механизм загрузки автоматически выполнят очистку целевой табличной части у объекта-приёмника. Поэтому при последовательном исполнении двух ПКГС данные, выгруженные из второй табличной части, полностью перезапишут данные, загруженные из первой.
Чтобы избежать очистки и объединить строки, необходимо переопределить источник данных для одной группы свойств, сформировав единую коллекцию до начала стандартной выгрузки.
Рассмотрим основной способ объединения данных с помощью языка запросов 1С. В КД 2.0 для ПКГС предусмотрен обработчик Перед обработкой. Если в данном обработчике присвоить переменной КоллекцияОбъектов собственное значение (например, типа ТаблицаЗначений), то стандартное получение данных платформой выполняться не будет.
Рассмотрим по шагам реализацию этого подхода:
Перед обработкой.ОБЪЕДИНИТЬ ВСЕ, и результат присваиваем переменной КоллекцияОбъектов.Посмотрим на пример кода в обработчике ПКГС Перед обработкой:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТЧ1.Номенклатура КАК Номенклатура,
| ТЧ1.Количество КАК Количество,
| ТЧ1.Цена КАК Цена,
| ТЧ1.Сумма КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТЧ1
|ГДЕ
| ТЧ1.Ссылка = &Ссылка
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ТЧ2.Номенклатура КАК Номенклатура,
| ТЧ2.Количество КАК Количество,
| ТЧ2.Цена КАК Цена,
| ТЧ2.Сумма КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг.Услуги КАК ТЧ2
|ГДЕ
| ТЧ2.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Источник);
КоллекцияОбъектов = Запрос.Выполнить().Выгрузить();
После выполнения этого кода платформа КД 2.0 возьмет готовую таблицу значений из КоллекцияОбъектов и перенесет строки в приёмник за один шаг, исключив повторную очистку.
Если обращения к базе данных через запрос не требуется (например, выгрузка выполняется из объектных данных в памяти), мы можем сформировать итоговую таблицу программно из объекта Источник.
Для этого в том же обработчике ПКГС Перед обработкой выгрузим первую ТЧ в переменную и дозаполним её строками из второй ТЧ:
// Выгружаем первую табличную часть
КоллекцияОбъектов = Источник.Товары.Выгрузить();
// Обходим вторую табличную часть и добавляем строки
Для Каждого СтрУслуги Из Источник.Услуги Цикл
ЗаполнитьЗначенияСвойств(КоллекцияОбъектов.Добавить(), СтрУслуги);
КонецЦикла;
Ещё один альтернативный вариант — передача данных второй табличной части (или обоих наборов) через структуру ВходящиеДанные или ПараметрыОбъекта с последующим заполнением на стороне приёмника.
Перед выгрузкой выгружаем вторую ТЧ в массив или таблицу значений и записываем в ПараметрыОбъекта.После загрузки считываем переданные данные из параметров и добавляем строки в целевой объект вручную с помощью метода Объект.ТЧ.Добавить().При использовании описанных способов обратите внимание на следующие особенности работы КД 2.0:
Перед обработкой команду Отказ = Истина;, иначе загрузка второго правила затрёт загруженные ранее данные.КоллекцияОбъектов должны совпадать с полем ИмяИсточника в подчиненных Правилах конвертации свойств (ПКС). При использовании запросов используйте псевдонимы колонок (КАК ИмяКолонки).