Работа с дополнительными реквизитами и сведениями — одна из самых частых задач при разработке в среде 1С, особенно если конфигурация построена на базе Библиотеки стандартных подсистем (БСП). Однако начинающие разработчики часто сталкиваются с ошибками вроде "Поле объекта не обнаружено" или "Значение не является значением объектного типа". В этой статье мы подробно разберем, почему возникают такие ошибки, как правильно обращаться к свойствам и как строить запросы к связанным справочникам.
Рассмотрим ситуацию, когда разработчик пытается получить доступ к дополнительным реквизитам напрямую из элемента формы. Типичный ошибочный код выглядит так:
Вкус = Элементы.Номенклатура1.ДополнительныеРеквизиты.Найти(...);
Проанализируем причину неудачи. Коллекция Элементы в управляемых формах содержит только визуальные компоненты — поля ввода, кнопки, таблицы. Даже если на форме отображается таблица дополнительных реквизитов, она является отображением данных, а не самими данными объекта. У элемента формы (визуального объекта) нет и не может быть свойства ДополнительныеРеквизиты. Именно поэтому система выдает ошибку "Поле объекта не обнаружено".
Для решения этой задачи нам необходимо обращаться не к элементам управления, а к данным. Если мы находимся в модуле формы, то обращаться нужно к основному реквизиту формы (например, Объект.ДополнительныеРеквизиты), а если в серверном контексте — непосредственно к ссылке на объект метаданных.
Следующая проблема, с которой столкнулся автор темы, — некорректный поиск самого свойства. Попытка найти свойство "Вкус" через метод НайтиПоРеквизиту("Имя", "Вкус") часто приводит к тому, что возвращается Неопределено. Это происходит потому, что реквизит "Имя" в плане видов характеристик ДополнительныеРеквизитыИСведения не всегда совпадает с тем, что мы видим в пользовательском интерфейсе.
Разберем, как сделать это правильно. В типовых конфигурациях свойства (характеристики) хранятся в ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения. Чтобы найти конкретный реквизит, лучше использовать следующий подход:
// Правильный поиск ссылки на свойство
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Вкус (Номенклатура)");
// Или, если мы знаем точное имя, заданное в конфигураторе/БСП
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("ИмяПредопределенногоНабора", "Справочник_Номенклатура");
Важный нюанс: в управляемых формах (УФ) нельзя обращаться к табличным частям через точку так же просто, как в обычных формах. Попытка вызвать метод Найти непосредственно у данных формы может закончиться ошибкой, если не учитывать контекст выполнения (сервер/клиент).
Когда нам нужно получить список всех возможных значений для конкретного дополнительного реквизита (например, все варианты вкусов: "Клубника", "Ваниль", "Шоколад"), мы обращаемся к справочнику ЗначенияСвойствОбъектов. Этот справочник является подчиненным (владельцем выступает элемент ПВХ).
Проанализируем ситуацию с запросом. Если мы хотим выбрать все доступные значения для конкретного свойства, запрос должен выглядеть следующим образом:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗначенияСвойств.Ссылка КАК Значение,
| ЗначенияСвойств.Наименование КАК Наименование
|ИЗ
| Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойств
|ГДЕ
| ЗначенияСвойств.Владелец = &СвойствоВладелец
| И НЕ ЗначенияСвойств.ЭтоГруппа
| И НЕ ЗначенияСвойств.ПометкаУдаления";
Запрос.УстановитьПараметр("СвойствоВладелец", НужноеСвойствоСсылка);
РезультатЗапроса = Запрос.Выполнить();
Обратите внимание: в поле Владелец в этом справочнике записывается ссылка на элемент ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения. Если ваш запрос "не реагирует", проверьте, что именно вы передаете в параметр &СвойствоВладелец. Это должна быть именно ссылка, а не строка или имя.
Для глубокого понимания темы важно различать два механизма хранения данных:
ДополнительныеРеквизиты. Они используются, когда данные нужны "внутри" объекта.ДополнительныеСведения. Они используются для хранения информации, которая не должна изменять сам объект (например, для добавления пометок к закрытым периодам).Если вам нужно в запросе отобрать Номенклатуру по значению дополнительного реквизита, не нужно обращаться к справочнику значений. Нужно обращаться к табличной части самой номенклатуры:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Товар
ИЗ
Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты
ГДЕ
ДопРеквизиты.Свойство = &СвойствоВкус
И ДопРеквизиты.Значение = &ЗначениеКлубника
В современных конфигурациях (УТ 11, ERP 2, БП 3.0) крайне рекомендуется использовать программный интерфейс БСП. Это избавит вас от необходимости писать сложные запросы вручную и защитит код от изменений в структуре метаданных. Разберем основные методы общего модуля УправлениеСвойствами.
Чтобы получить значение свойства для конкретного объекта, используйте функцию:
Значение = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаОбъект, СвойствоСсылка);
Если вам нужно получить все дополнительные реквизиты объекта сразу, можно воспользоваться методом:
ТаблицаСвойств = УправлениеСвойствами.СвойстваОбъекта(СсылкаНаОбъект);
// Таблица будет содержать колонки Свойство и Значение
Проанализировав эти подходы, мы видим, что использование стандартных подсистем значительно сокращает объем кода и уменьшает вероятность возникновения ошибок обращения к типам.
Подведем итоги нашего исследования:
Элементы для получения данных объекта. Используйте реквизит Объект или серверные вызовы.ПланыВидовХарактеристик выполняйте по ссылке или через предопределенные данные, избегайте поиска "по имени", если не уверены в уникальности заполнения реквизита Имя.ЗначенияСвойствОбъектов хранит только списки возможных значений. Сами привязки значений к объектам ищите в табличных частях (реквизиты) или регистрах (сведения).УправлениеСвойствами.Следуя этим правилам, вы сможете эффективно настраивать динамические свойства в любых конфигурациях 1С.