При настройке обмена данными между современными конфигурациями, такими как 1С:ERP Управление предприятием, и решениями предыдущих поколений, например, 1С:Управление производственным предприятием (УПП), разработчики часто сталкиваются с ошибками обращения к свойствам объектов. Одна из самых распространенных ошибок в механизме «1С:Конвертация данных 2.0» — это Ошибка получения значения свойства подчиненного объекта. Рассмотрим подробно, почему она возникает и как её устранить.
Типичная ситуация: при выгрузке документа Списание безналичных денежных средств из ERP в аналогичный документ УПП система прерывается с дампом ошибки, указывающим на отсутствие поля ДоговорКонтрагента. При этом визуально в конфигурации-приемнике (УПП) это поле существует в табличной части РасшифровкаПлатежа.
Проанализируем текст ошибки, который выдает обработка УниверсальныйОбменДаннымиXML:
Ошибка при выгрузке данных: {ВнешняяОбработка.УниверсальныйОбменДаннымиXML.МодульОбъекта(1327)}: Ошибка получения значения свойства подчиненного объекта (по имени свойства приемника) ПКО = СписаниеБезналичныхДенежныхСредств ПКС = 42 (--> ДоговорКонтрагента)... ОписаниеОшибки = Поле объекта не обнаружено (ДоговорКонтрагента)
Эта ошибка означает, что движок конвертации в правилах конвертации свойств (ПКС) под номером 42 пытается найти данные для заполнения договора, но не может обнаружить их в объекте-источнике или в программном коде обработчика. Выясним основные причины, почему это происходит:
Источник реквизит с именем, совпадающим с именем «Свойства приемника». В ERP договор может находиться в табличной части, а ПКС пытается найти его в шапке документа.ДоговорКонтрагента мог быть переименован в Договор или УдалитьДоговорКонтрагента.Как показывает практика, часто проблема кроется в том, что при настройке Правил Конвертации Групп Свойств (ПКГС) для табличной части РасшифровкаПлатежа, разработчик забывает указать источник для конкретной строки. Если движок конвертации начинает обрабатывать ПКС (свойство ДоговорКонтрагента), не имея ссылки на конкретную строку источника, он обращается к основному объекту (документу). А так как в шапке документа ERP договора может не быть, возникает ошибка Поле объекта не обнаружено.
Что нужно сделать: Проверьте, чтобы в настройках обмена для каждой строки табличной части передавался корректный объект-источник. Если вы формируете данные программно, убедитесь, что в структуру ВходящиеДанные или непосредственно в параметры ПКС передается объект, обладающий нужным свойством.
Если в ERP структура хранения договора сложная (например, зависит от вида хозяйственной операции), не полагайтесь на автоматический поиск свойства. Разберем, как прописать логику получения значения вручную в обработчике Перед выгрузкой для ПКС ДоговорКонтрагента.
Рассмотрим пример кода, который поможет избежать ошибки:
// Обработчик ПКС: Перед выгрузкой
// Проверяем наличие реквизита в источнике, чтобы избежать падения системы
Если СвойствоОбъекта(Источник, "Договор") Тогда
Значение = Источник.Договор;
ИначеЕсли СвойствоОбъекта(Источник, "ДоговорКонтрагента") Тогда
Значение = Источник.ДоговорКонтрагента;
Иначе
// Если это табличная часть, возможно, нужно брать данные из текущей строки
// или из входящих данных
Если ТипЗнч(ОбъектКоллекции) = Тип("СтрокаТабличнойЧасти") Тогда
Значение = ОбъектКоллекции.Договор;
КонецЕсли;
КонецЕсли;
// Если значение так и не найдено, можно отменить выгрузку конкретного свойства
Если Не ЗначениеЗаполнено(Значение) Тогда
Отказ = Истина;
КонецЕсли;
Многие разработчики отказываются от автоматического сопоставления (Имя ПКО) в пользу функции ВыгрузитьПоПравилу. Это дает гибкость, но требует осторожности. Проанализируем ситуацию: если в документе 4 разных типа операций, и для каждой нужен свой подход к выгрузке договора, убедитесь, что вы передаете в функцию именно ссылку на объект, а не строку или число.
Пример правильного вызова в обработчике:
// Пример в ПКС документа
Если Источник.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ОплатаПоставщику Тогда
// Передаем конкретный объект и указываем имя ПКО договора
ВыгрузитьПоПравилу(Источник.Договор, , , , "ДоговорыКонтрагентов");
ИначеЕсли Источник.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ВыдачаЗаймаСотруднику Тогда
// Для займов договор может не требоваться
Отказ = Истина;
КонецЕсли;
Важный нюанс: Если вы используете ВыгрузитьПоПравилу внутри ПКС, обязательно ставьте Отказ = Истина в конце обработчика, иначе система попытается выполнить стандартную выгрузку этого же свойства после вашего кода, что приведет к повторной ошибке.
Если вы уверены, что код написан правильно, но ошибка сохраняется, выясним причину в метаданных. При обновлении конфигураций ERP или УПП внутренние идентификаторы реквизитов могут измениться. Механизм «Конвертации данных» хранит кэш метаданных, который нужно обновлять.
Выполните следующие шаги:
MD83Exp.epf в актуальной базе ERP и выгрузите структуру метаданных в файл XML.СписаниеБезналичныхДенежныхСредств.ДоговорКонтрагента заново выберите источник и приемник из списков. Это «переподцепит» внутренние ссылки на метаданные.Когда договор в приемнике (УПП) должен быть один в шапке, а в источнике (ERP) их много в строках табличной части, используйте структуру ВходящиеДанные. Проанализируем алгоритм:
1. В ПКО документа в обработчике Перед выгрузкой соберите нужные данные в структуру.
// В ПКО документа
ВходящиеДанные = Новый Структура;
Если Источник.РасшифровкаПлатежа.Количество() > 0 Тогда
ВходящиеДанные.Вставить("ДоговорДляШапки", Источник.РасшифровкаПлатежа[0].Договор);
КонецЕсли;
2. В ПКС ДоговорКонтрагента установите флаг «Получать из входящих данных» и укажите имя ключа ДоговорДляШапки. Это гарантирует, что система не будет искать поле ДоговорКонтрагента в самом объекте Источник, тем самым предотвращая ошибку «Поле объекта не обнаружено».
Ошибка Поле объекта не обнаружено (ДоговорКонтрагента) при обмене ERP — УПП чаще всего является следствием того, что движок конвертации обращается к объекту Источник, ожидая найти в нем реквизит шапки, который в реальности находится в табличной части или называется иначе. Главное правило решения: всегда проверяйте наличие свойства функцией СвойствоОбъекта() или явно указывайте источник данных через ОбъектКоллекции или ВходящиеДанные.