При разработке правил обмена в Конвертации данных 2.1 (КД 2) часто возникают ситуации, когда источником данных выступает не конкретный объект информационной базы (документ или справочник), а произвольная структура. Это типичный сценарий, когда в базе-приемнике реквизит является ссылочным типом, а в базе-источнике эти данные «разбросаны» по разным полям или даже находятся в разных объектах. Рассмотрим подробно, как правильно настроить конвертацию в таких случаях, и почему стандартные механизмы могут оставлять поля пустыми.
Представим типичную задачу: в табличную часть документа нужно добавить выгрузку поля Договор. В базе-источнике договора как отдельного справочника может не существовать, но у нас есть данные: Номер, Дата и Сотрудник. Мы хотим создать на стороне приемника элемент справочника Договоры, а сотрудника превратить в Контрагента.
Проблема возникает тогда, когда мы формируем структуру для договора в обработчике ПередВыгрузкой ПКС (Правила конвертации свойств), но вложенный объект (Контрагент) не подхватывается. Это происходит потому, что при передаче Структуры вместо Ссылки механизм КД 2 теряет контекст объектного поиска (по GUID) и не всегда может автоматически определить, какое правило применить к полям этой структуры.
Проанализируем самый надежный подход, который позволяет гибко управлять процессом. Для этого нам необходимо создать специальное правило конвертации объектов (ПКО), которое умеет работать не со ссылкой, а с данными из структуры.
Договоры_Из_Структуры). В поле «Объект-источник» оставляем пустое значение, а в поле «Объект-приемник» выбираем СправочникСсылка.Договоры.Номера, Даты и Контрагента. Имена свойств-источников должны совпадать с ключами структуры, которую мы будем передавать.ПередВыгрузкой, мы формируем нашу структуру:
СтруктураДоговора = Новый Структура;
СтруктураДоговора.Вставить("Номер", ОбъектКоллекции.НомерДоговораГПХ);
СтруктураДоговора.Вставить("Дата", ОбъектКоллекции.ДатаДоговораГПХ);
// Передаем ссылку на сотрудника, которую позже обработаем
СтруктураДоговора.Вставить("Контрагент", ОбъектКоллекции.СотрудникДоговораГПХ);
Значение = СтруктураДоговора;
ИмяПКО = "Договоры_Из_Структуры";
Если автоматическое сопоставление через структуру все равно не заполняет вложенного контрагента, разберем ситуацию программной выгрузки. Рассмотрим пример кода, который можно разместить в ПКС Контрагент внутри нашего ПКО для договора.
Выясним причину: часто КД не понимает, что Сотрудник (Источник) должен стать Контрагентом (Приемник), если это не прописано явно. В обработчике ПередВыгрузкой для свойства Контрагент напишем следующее:
// ВходящиеДанные могут содержать дополнительные параметры,
// если мы хотим передать в ПКО Контрагента что-то особенное
ВходящиеДанные = Новый Структура;
ВходящиеДанные.Вставить("ЭтоДоговорГПХ", Истина);
// Вызываем выгрузку программно
// Источник.Контрагент — это ключ из структуры договора, созданной на предыдущем шаге
ВыгрузитьПоПравилу(Источник.Контрагент, , ВходящиеДанные, , "Сотрудники_В_Контрагенты");
// Сообщаем системе, что мы уже все выгрузили сами
ИмяПКО = "";
Этот метод гарантирует, что правило конвертации для контрагента будет вызвано принудительно с передачей всех необходимых параметров.
Посмотрим на ситуацию, когда данных в источнике недостаточно для полноценного поиска или создания объекта. Например, для контрагента нам нужны ИНН и Наименование, которых нет в справочнике сотрудников напрямую в удобном виде.
Проанализируем алгоритм использования ВходящихДанных:
ВходящиеДанные.ИНН или комбинации Наименование + ЮрФизЛицо.Пример подготовки данных для сложной выгрузки контрагента:
ДанныеКонтрагента = Новый Структура;
ДанныеКонтрагента.Вставить("ВидКонтрагента", "ФизЛицо");
ДанныеКонтрагента.Вставить("ИНН", Источник.Сотрудник.ФизическоеЛицо.ИНН);
ДанныеКонтрагента.Вставить("Наименование", Источник.Сотрудник.ФизическоеЛицо.Наименование);
// Передаем эти данные как входящие для правила Контрагента
ВыгрузитьПоПравилу(Неопределено, , ДанныеКонтрагента, , "Контрагенты_Без_Источника");
Разберем основные моменты, на которых спотыкаются разработчики:
ДатаДоговора, а в ПКС источником указано просто Дата, данные не будут переданы.СправочникСсылка), а вы передаете структуру, выполнение правила может прерваться с ошибкой или Отказ = Истина. Для структур используйте ПКО с пустым источником.ВыгрузитьПоПравилу внутри обработчиков ПКО нужно быть осторожным, чтобы не войти в бесконечную рекурсию.Совет: Для отладки таких процессов используйте метод Сообщить() в обработчиках ПередВыгрузкой и ПриВыгрузке. Если сообщение не выводится, значит, до выполнения правила цепочка вызовов просто не доходит из-за неверно указанного ИмяПКО или пустого значения Значение в родительском свойстве.
Таким образом, комбинируя использование структур в качестве Значения ПКС и явное указание правил через ИмяПКО или ВыгрузитьПоПравилу, можно решить любую задачу по трансформации данных между базами с разной архитектурой справочников.