При разработке правил обмена в конфигурации «1С:Конвертация данных 2.1» часто возникает задача преобразования одного документа в другой с переформированием табличной части. Например, требуется свернуть строки чеков или отчетов о розничных продажах и выгрузить их в документ ПриходныйКассовыйОрдер с заполнением табличной части РасшифровкаПлатежа. В процессе выгрузки разработчики нередко сталкиваются с ошибками вида «Поле объекта не обнаружено (РасшифровкаПлатежа)» или «Получение элемента по индексу для значения не определено».
Разберем по шагам, почему возникают такие ошибки и как правильно настроить правила конвертации данных.
Проанализируем типичные архитектурные ошибки при выгрузке:
Источник.РасшифровкаПлатежа). Если в исходном документе такой табличной части нет, возникает исключение.ВыгрузитьПоПравилу. Передавая структуру первым параметром функции, разработчик подменяет объект источника структурой. Если в ПКО прописаны стандартные обработчики, рассчитывающие на тип ДокументСсылка или ДокументОбъект (например, вызов Источник.Товары.Выгрузить()), обработка завершается с ошибкой «Поле объекта не обнаружено (Товары)».ВходящиеДанные. Если этот параметр не был передан в вызов ВыгрузитьПоПравилу (передан как Неопределено), движок падает при попытке получить значение по ключу.Отказ = Истина, это может привести к тому, что обработка прервет стандартную выборку остальных документов.Рассмотрим наиболее надежный и простой способ без ручного переопределения выборки в ПВД. Всю работу со сворачиванием и формированием строк мы переносим в правило конвертации группы свойств (ПКГС) нужной табличной части.
ZОтчет → ПриходныйКассовыйОрдер).РасшифровкаПлатежа. В настройках ПКГС очищаем поле «Источник» (оно должно быть пустым), а также проверяем, чтобы был снят флаг «Получить из входящих данных».КоллекцияОбъектов:
// Сворачиваем исходную табличную часть по ставке НДС
ТаблицаДляСвертки = Источник.Товары.Выгрузить();
ТаблицаДляСвертки.Свернуть("СтавкаНДС", "Сумма, СуммаНДС");
// Создаем и инициализируем результирующую коллекцию для приемника
КоллекцияОбъектов = Новый ТаблицаЗначений;
КоллекцияОбъектов.Колонки.Добавить("СуммаПлатежа");
КоллекцияОбъектов.Колонки.Добавить("СтавкаНДС");
КоллекцияОбъектов.Колонки.Добавить("СуммаНДС");
Для Каждого Строка Из ТаблицаДляСвертки Цикл
НСтр = КоллекцияОбъектов.Добавить();
НСтр.СуммаПлатежа = Строка.Сумма;
НСтр.СтавкаНДС = Строка.СтавкаНДС;
НСтр.СуммаНДС = Строка.СуммаНДС;
КонецЦикла;
В подчиненных правилах (ПКС) внутри этой группы в качестве источника указываем имена колонок созданной таблицы (СуммаПлатежа, СтавкаНДС, СуммаНДС). Значения будут автоматически последовательно извлекаться из сформированной таблицы КоллекцияОбъектов.
Для дополнительных реквизитов шапки, которых нет в источнике (например, ВидОперации), в соответствующих ПКС очищаем поле «Источник» и в обработчике «Перед выгрузкой» задаем значение напрямую:
Значение = "РозничнаяВыручка";
Разберем ситуацию, когда объект формируется полностью вручную из структуры и выгружается программно.
Посмотрим на сигнатуру функции ВыгрузитьПоПравилу:
ВыгрузитьПоПравилу(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО, ...)
Если в ПКО очистить объект-источник (оставить только приемник), то данные должны передаваться именно через третий параметр — ВходящиеДанные. Пошаговый алгоритм выглядит так:
ПриходныйКассовыйОрдер.
ТаблицаДляСвертки = Объект.Товары.Выгрузить();
ТаблицаДляСвертки.Свернуть("СтавкаНДС", "Сумма, СуммаНДС");
КоллекцияОбъектов = Новый ТаблицаЗначений;
КоллекцияОбъектов.Колонки.Добавить("СуммаПлатежа");
КоллекцияОбъектов.Колонки.Добавить("СтавкаНДС");
КоллекцияОбъектов.Колонки.Добавить("СуммаНДС");
Для Каждого Строка Из ТаблицаДляСвертки Цикл
НСтр = КоллекцияОбъектов.Добавить();
НСтр.СуммаПлатежа = Строка.Сумма;
НСтр.СтавкаНДС = Строка.СтавкаНДС;
НСтр.СуммаНДС = Строка.СуммаНДС;
КонецЦикла;
СтруктураДляВыгрузки = Новый Структура;
СтруктураДляВыгрузки.Вставить("Дата", Объект.Дата);
СтруктураДляВыгрузки.Вставить("ВалютаДокумента", Объект.ВалютаДокумента);
СтруктураДляВыгрузки.Вставить("ВидОперации", "РозничнаяВыручка");
СтруктураДляВыгрузки.Вставить("ВыручкаСНТТ", Истина);
СтруктураДляВыгрузки.Вставить("Номер", Объект.Номер);
СтруктураДляВыгрузки.Вставить("Организация", Объект.Фирма);
СтруктураДляВыгрузки.Вставить("Контрагент", Объект.Склад);
СтруктураДляВыгрузки.Вставить("СуммаДокумента", КоллекцияОбъектов.Итог("СуммаПлатежа"));
СтруктураДляВыгрузки.Вставить("РасшифровкаПлатежа", КоллекцияОбъектов);
// Передаем структуру в качестве входящих данных (3-й параметр):
ВыгрузитьПоПравилу(,, СтруктураДляВыгрузки,, "ПриходныйКассовыйОрдер");
// Отменяем стандартную выгрузку исходного документа
Отказ = Истина;
Если выгрузка документа выполняется не из ссылочного объекта, а через структуру, у документа в файле выгрузки отсутствует уникальный идентификатор (GUID). В этом случае в ПКО приемника обязательно нужно настроить поля поиска (отметить флаг «Поиск» у реквизитов Номер, Дата и Организация). Если этого не сделать, при загрузке нескольких документов каждый следующий будет перезаписывать предыдущий.