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