Как настроить произвольную выгрузку документа с табличной частью в 1С:Конвертация данных и исправить ошибку входящих данных?

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

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

Ошибка получения свойства объекта из входящих данных... ОписаниеОшибки = Получение элемента по индексу для значения не определено

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

Причина ошибки «Получение элемента по индексу для значения не определено»

Выясним причину возникновения ошибки. В типовом модуле обработки «Универсальный обмен данными XML» данная ошибка происходит в момент, когда в Правиле конвертации свойств (ПКС) или Правиле конвертации группы свойств (ПКГС) включен флаг «Получить из входящих данных», но сама переменная ВходящиеДанные не была инициализирована и равна Неопределено.

Когда мы формируем произвольную таблицу или выборку в ПВД через переменную ВыборкаДанных, эти данные поступают в ПКО в качестве объекта-источника (переменная Источник), а не во ВходящиеДанные. Движок обмена пытается обратиться к несуществующей структуре входящих данных по имени реквизита (как к элементу коллекции по ключу/индексу) и вызывает аварийное завершение процесса.

Важно четко понимать назначение этих контекстных переменных:

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

Способ 1. Выгрузка документа через ВыборкаДанных с вложенной таблицей

Если нам требуется выгрузить сводный документ, сформированный запросом в ПВД, проще всего представить строки документа как вложенную коллекцию внутри строки шапки.

Разберем по шагам настройку правил:

  1. В ПКО документа и во всех его ПКС и ПКГС снимаем флаги «Получить из входящих данных».
  2. В обработчике ПВД «Перед обработкой правила» формируем запрос. Поля шапки получаем на верхнем уровне, а строки табличной части — через конструкцию вложенной таблицы:

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	ПоступлениеТоваровУслуг.Контрагент КАК Контрагент,
|	ПоступлениеТоваровУслуг.ДоговорКонтрагента КАК ДоговорКонтрагента,
|	ПоступлениеТоваровУслуг.Организация КАК Организация,
|	ПоступлениеТоваровУслуг.Товары.(
|		Номенклатура КАК Номенклатура,
|		Количество КАК Количество,
|		Цена КАК Цена,
|		Сумма КАК Сумма,
|		СуммаНДС КАК СуммаНДС,
|		ЕдиницаИзмерения КАК ЕдиницаИзмерения
|	) КАК Товары
|ИЗ
|	Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг";

ВыборкаДанных = Запрос.Выполнить().Выгрузить();

При такой структуре каждая строка таблицы ВыборкаДанных представляет собой отдельный документ. Колонка Товары содержит полноценную таблицу значений, которая автоматически сопоставится с ПКГС «Товары», если имена колонок совпадают с именами свойств источника.

Способ 2. Ручная группировка и программная передача через ВыгрузитьПоПравилу

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

Посмотрим на пример кода в обработчике ПВД «Перед обработкой правила»:


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	ПоступлениеТовары.Ссылка.Контрагент КАК Контрагент,
|	ПоступлениеТовары.Номенклатура КАК Номенклатура,
|	СУММА(ПоступлениеТовары.Количество) КАК Количество,
|	СУММА(ПоступлениеТовары.Сумма) КАК Сумма,
|	СУММА(ПоступлениеТовары.СуммаНДС) КАК СуммаНДС
|ИЗ
|	Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТовары
|СГРУППИРОВАТЬ ПО
|	ПоступлениеТовары.Ссылка.Контрагент,
|	ПоступлениеТовары.Номенклатура
|ИТОГИ ПО
|	Контрагент";

Результат = Запрос.Выполнить();
ВыборкаКонтрагентов = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаКонтрагентов.Следующий() Цикл
	
	// Формируем таблицу товаров для текущего сводного документа
	ТаблицаТовары = Новый ТаблицаЗначений;
	ТаблицаТовары.Колонки.Добавить("Номенклатура");
	ТаблицаТовары.Колонки.Добавить("Количество");
	ТаблицаТовары.Колонки.Добавить("Цена");
	ТаблицаТовары.Колонки.Добавить("Сумма");
	ТаблицаТовары.Колонки.Добавить("СуммаНДС");
	
	ВыборкаСтрок = ВыборкаКонтрагентов.Выбрать();
	Пока ВыборкаСтрок.Следующий() Цикл
		НоваяСтрока = ТаблицаТовары.Добавить();
		НоваяСтрока.Номенклатура = ВыборкаСтрок.Номенклатура;
		НоваяСтрока.Количество   = ВыборкаСтрок.Количество;
		НоваяСтрока.Сумма        = ВыборкаСтрок.Сумма;
		НоваяСтрока.СуммаНДС     = ВыборкаСтрок.СуммаНДС;
		// Пересчитываем среднюю цену
		НоваяСтрока.Цена = ?(ВыборкаСтрок.Количество <> 0, ВыборкаСтрок.Сумма / ВыборкаСтрок.Количество, 0);
	КонецЦикла;
	
	// Заполняем структуру исходящих данных
	ИсходящиеДанные = Новый Структура;
	ИсходящиеДанные.Вставить("Контрагент", ВыборкаКонтрагентов.Контрагент);
	ИсходящиеДанные.Вставить("Товары",     ТаблицаТовары);
	
	// Вызываем выгрузку по ПКО без объекта-источника
	ВыгрузитьПоПравилу(,, ИсходящиеДанные,, "ПоступлениеТоваровУслуг");
	
КонецЦикла;

В этом сценарии в ПКО «ПоступлениеТоваровУслуг» мы устанавливаем флаг «Получить из входящих данных» для реквизита Контрагент и ПКГС Товары, так как данные передаются через структуру ИсходящиеДанные.

Выгрузка ссылочных типов (Номенклатура, Единицы измерения)

При программном формировании табличных частей важно убедиться, что для всех ссылочных полей настроены свои ПКО. Если реквизит Номенклатура не переносится или создается пустым, проверяем следующие параметры:

  1. В ПКС «Номенклатура» внутри группы «Товары» должно быть указано соответствующее ПКО (например, Номенклатура).
  2. Для подчиненных справочников (единицы измерения, спецификации, договоры) также должны существовать рабочие ПКО, по которым конфигурация сможет сопоставить объекты в базе-приемнике.
  3. Если в базе-приемнике поиск осуществляется по уникальным полям (код, наименование, артикул), в ПКО справочника должны быть отмечены соответствующие поля поиска.
← На главную