При настройке правил обмена в конфигурации «1С:Конвертация данных 2.1» разработчики нередко сталкиваются с ошибками вида «Ошибка получения значения свойства объекта (по имени свойства источника)» с диагностикой «Поле объекта не обнаружено». Ошибка возникает в момент выгрузки данных через обработку УниверсальныйОбменДаннымиXML. Разберем конкретную ситуацию, выясним внутренние причины такого поведения платформы и подробно рассмотрим надежные способы решения проблемы.
Рассмотрим типовой стек ошибки, который регистрируется в протоколе выгрузки данных:
ПКО: Контрагенты (Справочник: Контрагенты)
ПКС: 6 (Комментарий --> Комментарий)
Объект: Аполо 49 (Организация)
СвойствоПриемника: Комментарий (Строка)
ОписаниеОшибки: Поле объекта не обнаружено (Комментарий)
ПозицияМодуля: Обработка.УниверсальныйОбменДаннымиXML.МодульОбъекта
Проанализируем эти данные. Правило конвертации свойств (ПКС) для реквизита Комментарий пытается прочитать значение из реквизита источника. При этом правило конвертации объекта (ПКО) называется Контрагенты, а фактический объект, попавший на вход обработчику, имеет тип СправочникСсылка.Организации. У справочника организаций в базе-источнике реквизит Комментарий отсутствует либо называется иначе, поэтому обращение к нему вызывает исключение платформы.
Почему ссылка на организацию попала в правило конвертации контрагентов? В подавляющем большинстве случаев это связано с выгрузкой составных реквизитов из других объектов. Например, в регистрах сведений (таких как СоответствиеОрганизацийЕГАИС), документах или штрихкодах реквизиты владельца могут принимать как значение типа СправочникСсылка.Контрагенты, так и СправочникСсылка.Организации.
Если в родительском ПКО для свойства составного типа жестко задано подчиненное правило конвертации Контрагенты, конвертер безоговорочно применяет его ко всем выгружаемым ссылкам, независимо от их реального типа. Когда в составной реквизит попадает организация, механизм выгрузки пытается разобрать её по структуре контрагента.
Наиболее контролируемый и правильный подход — программно указать системе, какое именно ПКО должно обрабатывать конкретный тип значения. Для этого перейдем в конфигурацию «Конвертация данных 2.1», откроем ПКО исходного объекта (например, регистра сведений или документа) и найдем ПКС составного реквизита.
В форме настройки ПКС перейдем в обработчик событий «ПередОбработкой». На этом этапе значение реквизита уже получено и помещено в предопределенную переменную Значение. Проанализируем ее тип и переопределим переменную ИмяПКО:
Если ТипЗнч(Значение) = Тип("СправочникСсылка.Организации") Тогда
ИмяПКО = "Организации";
ИначеЕсли ТипЗнч(Значение) = Тип("СправочникСсылка.Контрагенты") Тогда
ИмяПКО = "Контрагенты";
КонецЕсли;
Обратим внимание на важную деталь: обращаться к реквизиту через конструкцию Источник.Контрагент не всегда безопасно, так как источник при выполнении различных алгоритмов может быть передан не ссылкой или выборкой, а произвольной структурой или таблицей значений. Переменная Значение инициализируется обработкой обмена автоматически и всегда содержит актуальные данные для конвертации текущего свойства.
Механизм КД 2.1 умеет сопоставлять типы данных автоматически. Если в настройках ПКС составного реквизита очистить поле «Правило конвертации», оставив его пустым, универсальная обработка обмена при выгрузке выполнит следующее:
Значение с помощью функции ТипЗнч().Данный вариант работает идеально, если в конвертации нет нескольких альтернативных ПКО для одного и того же типа метаданных (например, если нет двух разных правил для справочника Контрагенты с одинаковым приоритетом).
Чтобы гарантировать устойчивость конфигурации конвертации при дальнейших доработках, настроим защитный барьер непосредственно в самом ПКО Контрагенты. Это не позволит правилу обрабатывать сторонние типы объектов, даже если разработчик допустит ошибку в других правилах.
Откроем ПКО Контрагенты и в обработчике «ПередВыгрузкой» напишем условие проверки типа входящего источника:
Если ТипЗнч(Источник) <> Тип("СправочникСсылка.Контрагенты")
И ТипЗнч(Источник) <> Тип("СправочникОбъект.Контрагенты") Тогда
Отказ = Истина;
КонецЕсли;
Установка параметра Отказ = Истина прерывает выгрузку некорректного объекта данным правилом и предотвращает возникновение критических ошибок при чтении несуществующих полей.
Разберем по шагам алгоритм диагностики и устранения сбоя:
Аполо 49).ИмяПКО в обработчике ПередОбработкой.УниверсальныйОбменДаннымиXML в исходной базе и запускаем процедуру выгрузки повторно.Если после внесения изменений сообщение об ошибке повторяется без изменений, убедимся, что файл правил был перезагружен в обработку выгрузки, так как УниверсальныйОбменДаннымиXML кеширует правила до момента явной перезагрузки файла пользователем.