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