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