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