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