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