При настройке правил обмена в конфигурации «1С:Конвертация данных 2.1» (КД 2) разработчики часто сталкиваются с задачей, когда в базе-приемнике требуется заполнить реквизит, которого вообще нет в базе-источнике, либо его заполнение требует сложной логики сопоставления. Классический пример: в источнике есть только строковое поле комментария (например, содержащее код бюджетной классификации или произвольный текст «Васька дурак»), а в приемнике этот текст должен превратиться в полноценную ссылку на элемент справочника (например, Контрагенты или ВидыНалоговИПлатежейВБюджет).
В этой статье мы подробно разберем, как правильно передавать произвольную текстовую информацию из источника в приемник, почему стандартные переменные вроде ИсходящиеДанные не попадают в файл XML, и рассмотрим продвинутые сценарии работы с параметрами объектов в КД 2.
Начинающие специалисты по интеграции часто пытаются решить задачу «в лоб». В обработчике «Перед выгрузкой» Правила конвертации объекта (ПКО) или свойства (ПКС) они пишут следующий код:
ИсходящиеДанные = Новый Структура;
ИсходящиеДанные.Вставить("КодБК", "АХАХАХАХА");
Однако при анализе сформированного XML-файла обмена оказывается, что строка «АХАХАХАХА» там полностью отсутствует. Проанализируем ситуацию и выясним причину такого поведения платформы.
Дело в том, что переменные ИсходящиеДанные и ВходящиеДанные в КД 2 спроектированы исключительно как внутренний транспорт в оперативной памяти выгружающего приложения. Они живут только на стороне источника в процессе работы обработки выгрузки и служат для обмена контекстом между обработчиками. Схема их движения строго регламентирована:
В сам XML-файл обмена эти структуры не записываются. База-приемник при чтении файла ничего о них не знает. Для того чтобы физически передать данные через файл, нужен принципиально другой механизм — параметры объектов.
Для того чтобы передать строку из источника и прочитать ее при загрузке в приемнике, мы должны использовать специальную опцию в ПКС. Разберем этот процесс по шагам:
КодБК).
Значение = "АХАХАХАХА"; // Здесь может быть обращение к реквизитам источника, например: Источник.Комментарий
При выгрузке КД 2 сгенерирует в XML-файле узел следующего вида:
<ЗначениеПараметра Имя="КодБК" Тип="Строка">АХАХАХАХА</ЗначениеПараметра>
Этот параметр будет успешно доставлен в базу-приемник вместе с объектом.
Теперь посмотрим, как использовать переданное значение при загрузке. При чтении файла загрузчик считывает параметры и помещает их в специальную структуру — соответствие ПараметрыОбъекта.
Обратите внимание: обращаться к параметрам следует в обработчиках загрузки ПКО, оптимально — в обработчике «После загрузки». В обработчиках «Перед записью» или «При записи» самого объекта конфигурации эта структура уже будет недоступна, так как управление передается платформенным механизмам записи 1С.
Рассмотрим пример кода в обработчике «После загрузки» ПКО:
Если ПараметрыОбъекта <> Неопределено Тогда
КодБК = ПараметрыОбъекта.Получить("КодБК");
Если ЗначениеЗаполнено(КодБК) Тогда
// Выполняем поиск нужного элемента в базе-приемнике по полученной строке
НайденныйНалог = Справочники.ВидыНалоговИПлатежейВБюджет.НайтиПоРеквизиту("КодБК", КодБК);
Если ЗначениеЗаполнено(НайденныйНалог) Тогда
Объект.Налог = НайденныйНалог;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Этот код гарантирует, что если параметр был успешно передан, система найдет соответствующий элемент в базе-приемнике и подставит его в создаваемый объект.
Хотя ручной поиск в обработчике «После загрузки» решает задачу, КД 2 предоставляет более красивый декларативный способ сопоставления объектов по строковому представлению. Мы можем создать отдельное ПКО, которое будет принимать строку на входе и автоматически искать объект в приемнике.
Рассмотрим по шагам реализацию этого подхода:
ВидыНалоговИПлатежейВБюджет (источник оставляем пустым). Назовем его, например, ВидыНалогов_ПоСтроке.КодБК, установим для него флаг «Поиск». В обработчике «Перед выгрузкой» для этого ПКС напишем:
Значение = Источник; // Источником здесь будет выступать переданная строка
Налог укажем созданное нами ПКО ВидыНалогов_ПоСтроке в качестве правила конвертации.Налог документа напишем код передачи строки:
Значение = Источник.Комментарий; // Передаем строковое значение комментария в ПКО поиска
Таким образом, КД 2 выполнит всю работу по поиску и сопоставлению автоматически, без написания громоздких ручных запросов при загрузке. Это делает архитектуру правил обмена чистой и легко поддерживаемой.
Иногда возникает необходимость передать специфический строковый параметр не для всего документа целиком, а для каждой строки его табличной части индивидуально. КД 2 поддерживает и эту возможность.
Для реализации этого сценария выполним следующие действия:
Товары).КомментарийСтроки) и установим флаг «Передавать данные в параметр».ОбъектКоллекции):
Значение = ОбъектКоллекции.СпецифическийКомментарий;
На стороне приемника при чтении XML-файла КД 2 сформирует в структуре ПараметрыОбъекта массив соответствий для строк табличной части. Имя этого массива формируется автоматически по шаблону: [ИмяТабличнойЧасти] + "ТабличнаяЧасть" (в нашем примере — ТоварыТабличнаяЧасть).
Посмотрим, как прочитать эти строковые параметры строк в обработчике ПКО «После загрузки»:
ПараметрыТЧ = ПараметрыОбъекта.Получить("ТоварыТабличнаяЧасть");
Если ПараметрыТЧ <> Неопределено Тогда
Для Индекс = 0 По Объект.Товары.Количество() - 1 Цикл
СтрокаПараметров = ПараметрыТЧ[Индекс];
Если СтрокаПараметров <> Неопределено Тогда
ЗначениеПараметраСтроки = СтрокаПараметров.Получить("КомментарийСтроки");
Если ЗначениеЗаполнено(ЗначениеПараметраСтроки) Тогда
// Заполняем реквизит текущей строки табличной части в приемнике
ТекущаяСтрока = Объект.Товары[Индекс];
ТекущаяСтрока.ДополнительныеСведения = ЗначениеПараметраСтроки;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
В сложных интеграционных сценариях бывает необходимо передать не одну строку, а целый массив, структуру или даже таблицу значений. Чтобы не плодить множество ПКС-параметров, мы можем упаковать сложные данные в XML-строку на стороне источника и распаковать их на стороне приемника.
Проанализируем пример использования сериализации. На стороне источника в обработчике «Перед выгрузкой» ПКС-параметра пишем:
ДанныеДляПередачи = Новый Структура;
ДанныеДляПередачи.Вставить("СтавкаНДС", 20);
ДанныеДляПередачи.Вставить("КодФилиала", "012");
ДанныеДляПередачи.Вставить("ТипОперации", "Импорт");
// Упаковываем структуру в системную строку 1С
Значение = ЗначениеВСтрокуВнутр(ДанныеДляПередачи);
При загрузке в обработчике ПКО «После загрузки» мы можем легко восстановить исходный объект 1С и прочитать его свойства:
СериализованныеДанные = ПараметрыОбъекта.Получить("СложныеДанные");
Если ЗначениеЗаполнено(СериализованныеДанные) Тогда
Попытка
// Восстанавливаем структуру из строки
ПолученныеДанные = ЗначениеИзСтрокиВнутр(СериализованныеДанные);
// Заполняем реквизиты объекта приемника
Объект.СтавкаНДС = ПолученныеДанные.СтавкаНДС;
Объект.Комментарий = "Загружено по филиалу: " + ПолученныеДанные.КодФилиала;
Исключение
ЗаписьЖурналаРегистрации("Конвертация", УровеньЖурналаРегистрации.Предупреждение,,, "Не удалось распаковать параметры объекта.");
КонецПопытки;
КонецЕсли;
Иногда переданные параметры требуются не в момент обработки загрузки КД, а непосредственно при записи или проведении объекта в базе-приемнике (например, в модуле объекта в процедурах ПередЗаписью(), ПриЗаписи() или в подписках на события платформы).
Поскольку ПараметрыОбъекта доступны только внутри обработчиков загрузки правил обмена, мы можем использовать стандартный механизм платформы — свойство ДополнительныеСвойства, которое сохраняется у объекта на протяжении всей транзакции записи.
Для этого в обработчике ПКО «После загрузки» перенесем данные из параметров КД в свойства объекта:
Если ПараметрыОбъекта <> Неопределено Тогда
КодБК = ПараметрыОбъекта.Получить("КодБК");
Если ЗначениеЗаполнено(КодБК) Тогда
// Помещаем значение в ДополнительныеСвойства платформенного объекта
Объект.ДополнительныеСвойства.Вставить("ЗагруженныйКодБК", КодБК);
КонецЕсли;
КонецЕсли;
Теперь в конфигурации-приемнике, непосредственно в модуле самого объекта (например, документа), мы можем перехватить это значение в процедуре записи:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если ДополнительныеСвойства.Свойство("ЗагруженныйКодБК") Тогда
ЗначениеКода = ДополнительныеСвойства.ЗагруженныйКодБК;
// Наша бизнес-логика в конфигурации-приемнике
ЭтотОбъект.Комментарий = "Код БК при загрузке: " + ЗначениеКода;
КонецЕсли;
КонецПроцедуры
Использование этого приема позволяет связать гибкость настройки правил «1С:Конвертация данных» с внутренней бизнес-логикой и механизмами проведения принимающей конфигурации.
Мы подробно изучили различные способы передачи произвольных строковых данных между базами. Понимание разницы между внутренними структурами оперативной памяти (ИсходящиеДанные) и физической передачей через файлы параметров позволяет создавать производительные, масштабируемые и отказоустойчивые правила интеграции в среде 1С.