Как передать массив структур через параметры в Конвертации данных 2.0

Программист 1С v8.3 (Обычные формы) 1С:Комплексная автоматизация Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Попытка выгрузить произвольный массив структур через глобальный параметр конвертации нередко приводит к тому, что на стороне приемника в обработчиках загрузки значение параметра оказывается равным Неопределено. Разберем причины такого поведения, устраним ошибку передачи параметров и рассмотрим более надежные, типовые варианты реализации через механизмы Конвертации данных 2.0.

Почему глобальный параметр возвращает «Неопределено» при загрузке

Проанализируем основные причины, из-за которых переданные в источнике данные не считываются на стороне приемника:

  1. Неправильная инициализация параметра: если для параметра установлен признак «Передавать при выгрузке», его значение должно определяться в персональном обработчике самого параметра «Перед выгрузкой» через предопределенную переменную Значение. Если параметр заполняется в глобальном событии «Перед выгрузкой данных» через конструкцию Параметры.ИмяПараметра = ..., движок КД 2.0 не включает его в итоговый XML-блок параметров выгрузки.
  2. Ошибки сериализации нестандартных типов: встроенный XML-сериализатор КД 2.0 корректно выгружает массивы и структуры только в том случае, если все содержащиеся в них значения имеют примитивные типы (Число, Строка, Дата, Булево). Присутствие ссылочных типов (например, ссылки на счет учета или субконто) приводит к сбою десериализации или обнулению параметра.
  3. Несоответствие имен ключей: опечатки в ключах структуры при выгрузке и загрузке приводят к ошибкам времени выполнения.

Вариант 1. Корректная передача массива через параметры и сериализацию

Если логика требует передачи массива данных именно через глобальный параметр конвертации, разберем по шагам правильную реализацию.

Шаг 1. Настройка параметра в КД 2.0. Создаем параметр МассивПоступлениеУслугСодержание. Устанавливаем флаги «Передавать при выгрузке» и «Использовать при загрузке».

Шаг 2. Заполнение в обработчике параметра «Перед выгрузкой». Открываем обработчик «Перед выгрузкой» конкретного параметра и формируем массив с примитивными типами данных:


МассивДанных = Новый Массив;

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

Запрос.УстановитьПараметр("ДатаНачала", Параметры.ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", Параметры.ДатаОкончания);

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
	СтруктураСтроки = Новый Структура;
	СтруктураСтроки.Вставить("НомерДокумента", Выборка.НомерДокумента);
	СтруктураСтроки.Вставить("ДатаДокумента", Выборка.ДатаДокумента);
	СтруктураСтроки.Вставить("НомерСтрокиДок", Выборка.НомерСтрокиДок);
	СтруктураСтроки.Вставить("Содержание", Выборка.Содержание);
	СтруктураСтроки.Вставить("СчетУчета", Выборка.СчетУчета);
	
	МассивДанных.Добавить(СтруктураСтроки);
КонецЦикла;

// Присваиваем служебной переменной Значение, а не Параметры.ИмяПараметра
Значение = ЗначениеВСтрокуВнутр(МассивДанных);

Шаг 3. Чтение параметра в событии конвертации «После загрузки параметров». В обработчике события распаковываем строку обратно в коллекцию и помещаем в таблицу значений для быстрого поиска:


Параметры.ТаблицаПоступлениеУслугСодержание = Новый ТаблицаЗначений;
Параметры.ТаблицаПоступлениеУслугСодержание.Колонки.Добавить("НомерДокумента", Новый ОписаниеТипов("Строка"));
Параметры.ТаблицаПоступлениеУслугСодержание.Колонки.Добавить("ДатаДокумента", Новый ОписаниеТипов("Дата"));
Параметры.ТаблицаПоступлениеУслугСодержание.Колонки.Добавить("НомерСтрокиДок", Новый ОписаниеТипов("Число"));
Параметры.ТаблицаПоступлениеУслугСодержание.Колонки.Добавить("Содержание", Новый ОписаниеТипов("Строка"));
Параметры.ТаблицаПоступлениеУслугСодержание.Колонки.Добавить("СчетУчета", Новый ОписаниеТипов("Строка"));

Если ЗначениеЗаполнено(Параметры.МассивПоступлениеУслугСодержание) Тогда
	МассивДанных = ЗначениеИзСтрокиВнутр(Параметры.МассивПоступлениеУслугСодержание);
	Для Каждого СтрДанных Из МассивДанных Цикл
		ЗаполнитьЗначенияСвойств(Параметры.ТаблицаПоступлениеУслугСодержание.Добавить(), СтрДанных);
	КонецЦикла;
КонецЕсли;

Вариант 2. Штатное решение через ПКО без источника и ВыгрузитьПоПравилу (рекомендуемый)

Хранение всех строк в глобальном параметре имеет существенные архитектурные недостатки: потребление памяти, ручной поиск дублей и ручное создание элементов справочников методом СоздатьЭлемент(). Ручное создание объектов в обход механизмов КД 2.0 не регистрирует сопоставление ссылок в служебных таблицах, что приводит к появлению дубликатов номенклатуры при повторных обменах.

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

  1. Создаем ПКО для справочника Номенклатура с именем Номенклатура_УслугаПоСодержанию. Поле «Источник» оставляем пустым, а поле «Приемник» задаем как СправочникСсылка.Номенклатура.
  2. В данном ПКО настраиваем ПКС Наименование, НаименованиеПолное, ТипНоменклатуры, выбрав поля поиска (например, Наименование). В ПКС ТипНоменклатуры в обработчике «Перед выгрузкой» устанавливаем фиксированное значение Перечисления.ТипыНоменклатуры.Услуга.
  3. В основном ПКО документа (например, ПоступлениеТоваровУслуг) переходим в ПКС табличной части Товары.Номенклатура. В обработчике «Перед выгрузкой» переопределяем стандартную логику:

Если Не ЗначениеЗаполнено(ОбъектКоллекции.Номенклатура) И ЗначениеЗаполнено(ОбъектКоллекции.Содержание) Тогда
	Входящие = Новый Структура;
	Входящие.Вставить("Наименование", СокрЛП(ОбъектКоллекции.Содержание));
	Входящие.Вставить("НаименованиеПолное", СокрЛП(ОбъектКоллекции.Содержание));
	
	ВыгрузитьПоПравилу(,, Входящие,, "Номенклатура_УслугаПоСодержанию");
	Отказ = Истина;
КонецЕсли;

При таком подходе движок конвертации автоматически выполнит поиск подходящей услуги в базе-приемнике по наименованию. Если услуга не найдена, она будет корректно создана, заполнена и привязана к строке документа без необходимости писать сложные ручные запросы и алгоритмы создания объектов в событии ПослеЗагрузки.

Особенности проведения документов после загрузки

Обратите внимание на вызов проведения документов в обработчиках загрузки. Не рекомендуется вызывать Объект.Записать(РежимЗаписиДокумента.Проведение) и функции проведения регламентированного учета непосредственно внутри события ПослеЗагрузки.

На этапе чтения одного объекта другие связанные данные (договоры, статьи расходов, регистры) могут быть еще не загружены. Проведение документов следует выполнять стандартными средствами обработки обмена (флаг «Выполнять отложенное проведение») либо централизованно в глобальном событии конвертации «После загрузки всех данных».

← На главную