При разработке правил обмена в конфигурации 1С:Конвертация данных 2.0 (КД 2.0) нередко возникает задача: выгрузить реквизит составного типа или объект табличной части по определенному правилу конвертации объектов (ПКО) в зависимости от условий (например, от типа документа-источника или типа самого значения). Разберем, почему прямой вызов ВыгрузитьПоПравилу внутри произвольного алгоритма ПВД может не сработать так, как ожидается, как работает механизм приоритетов правил и как правильно переопределять ПКО динамически.
Проанализируем распространенную ошибку: при обработке выборки в ПВД разработчик вызывает метод ВыгрузитьПоПравилу() для отдельного реквизита или субконто, а затем добавляет строку в табличную часть выгружаемого документа. В таком сценарии метод ВыгрузитьПоПравилу() действительно создает отдельный узел в результирующем XML-файле по указанному ПКО. Однако когда следом начинает выгружаться сам документ и его табличная часть, платформа 1С повторно запускает конвертацию ссылки для каждого реквизита табличной части через стандартные правила конвертации свойств (ПКС).
Если в самом ПКС не указано конкретное правило, система определяет ПКО автоматически: она ищет среди всех правил подходящее по типу источника и выбирает то, у которого установлен наибольший приоритет. В результате ссылка в строке табличной части конвертируется по правилу по умолчанию, перезаписывая или дублируя поведение.
Выясним, как платформа определяет правило по умолчанию при наличии нескольких ПКО с одинаковым объектом-источником:
Приоритет (вкладка «Дополнительно» в настройках ПКО).200 будет выбрано платформой вместо правила с приоритетом 149. Чем выше число, тем выше приоритет правила при автоматическом сопоставлении по типу.Наиболее надежный и правильный способ управлять выбором правила для реквизита шапки или табличной части — переопределять переменную ИмяПКО непосредственно в обработчике «Перед выгрузкой» соответствующего ПКС.
В контексте обработчика ПКС для реквизита табличной части доступны ключевые переменные:
ОбъектОснование — ссылка на сам документ или объект-источник, которому принадлежит табличная часть.Источник — значение текущего выгружаемого реквизита (например, ссылка на контрагента или субконто).ИмяПКО — имя правила конвертации объекта, которое должно быть применено для выгрузки данного значения.Посмотрим на пример кода в обработчике «Перед выгрузкой» ПКС табличной части:
Если ТипЗнч(ОбъектОснование) = Тип("ДокументСсылка.ПлатежноеПоручениеИсходящее") Тогда
Если ТипЗнч(Источник) = Тип("СправочникСсылка.Контрагенты") Тогда
ИмяПКО = "КонтрагентыВКонтрагенты2";
КонецЕсли;
КонецЕсли;
При таком подходе для всех строк табличной части документа ПлатежноеПоручениеИсходящее контрагенты будут выгружаться строго по правилу КонтрагентыВКонтрагенты2, независимо от глобальных приоритетов других ПКО.
Если данные собираются сложным произвольным запросом в ПВД, разберем альтернативный вариант — передачу сформированной структуры документа целиком, минуя поэлементную выгрузку ссылок в цикле:
ИсходящиеДанные, куда помещаем реквизиты шапки документа и таблицу значений с готовыми строками табличной части.
ВыгрузитьПоПравилу(, , ИсходящиеДанные, , "ИмяПКОДокумента");
ИмяПКО для ссылочных полей.Обратим внимание на поведение базы-приемника при загрузке: если один и тот же элемент источника выгружается по разным ПКО в разные справочники приемника, необходимо следить за алгоритмом поиска. Поиск по УникальномуИдентификатору (GUID) может привести к коллизиям, если разные объекты приемника получат одинаковый GUID. В таких случаях для альтернативного ПКО рекомендуется настраивать поиск по полям поиска (например, по комбинации ИНН/КПП или Наименованию), отключив поиск по внутреннему идентификатору.