Разработка и Конфигурация · 12 мин
Как получить значение дополнительного реквизита в 1С 8.3 программно
Способы программного получения значений дополнительных реквизитов в 1С 8.3: табличная часть объекта, запрос, БСП. Примеры кода, проверка результата и типичные ошибки.
Дополнительные реквизиты в 1С 8.3 хранятся не в основной таблице объекта, а в отдельной табличной части «ДополнительныеРеквизиты», поэтому простое обращение через точку вида Справочник.Цвет не сработает. Чтобы получить значение, нужно либо прочитать эту табличную часть из объекта, либо выполнить запрос к таблице дополнительных реквизитов, либо воспользоваться механизмами Библиотеки стандартных подсистем (БСП), если она встроена в конфигурацию.
Выбор способа зависит от контекста: в модуле объекта удобнее работать напрямую с табличной частью, при обходе больших выборок быстрее запрос, а в типовых конфигурациях на базе БСП правильнее использовать готовые функции, которые учитывают и дополнительные сведения, и особенности хранения. Ниже разобраны все три подхода с примерами кода, проверкой результата и типичными ошибками.
Где физически хранятся значения дополнительных реквизитов
Механизм дополнительных реквизитов реализован через план видов характеристик «ДополнительныеРеквизитыИСведения». Каждый созданный в режиме предприятия реквизит (например, «Цвет» или «Гарантийный срок») — это элемент этого плана видов характеристик. Сами значения для конкретных объектов записываются в табличную часть «ДополнительныеРеквизиты» соответствующего справочника или документа, где каждая строка содержит ссылку на свойство и его значение.
Важно различать дополнительные реквизиты и дополнительные сведения. Реквизиты хранятся в табличной части объекта и доступны для отбора в списках, а сведения — в отдельном регистре сведений «ДополнительныеСведения». Код для их чтения отличается, и путаница между ними — одна из самых частых причин «пустого» результата.
Способ 1: чтение табличной части объекта
Самый прямой способ — получить объект методом ПолучитьОбъект() и найти нужную строку в табличной части «ДополнительныеРеквизиты» по ссылке на свойство. Подходит, когда объект уже открыт для чтения или изменения, например в обработчиках формы или модуля объекта.
Функция ПолучитьЗначениеДопРеквизита(СсылкаНаОбъект, СвойствоСсылка)
ОбъектДанных = СсылкаНаОбъект.ПолучитьОбъект();
ПараметрыОтбора = Новый Структура("Свойство", СвойствоСсылка);
НайденныеСтроки = ОбъектДанных.ДополнительныеРеквизиты.НайтиСтроки(ПараметрыОтбора);
Если НайденныеСтроки.Количество() > 0 Тогда
Возврат НайденныеСтроки[0].Значение;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Обратите внимание: ПолучитьОбъект() вычитывает объект из базы целиком, что при массовом обходе тысяч элементов даёт заметную нагрузку. Для пакетной обработки этот способ не подходит — используйте запрос.
Чтобы получить ссылку на свойство, найдите его в плане видов характеристик по наименованию:
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения
.НайтиПоНаименованию("Гарантийный срок", Истина);
Способ 2: получение значения запросом
Запрос к таблице дополнительных реквизитов — оптимальный вариант для отчётов, обработок и выборок по многим объектам. Таблица называется по шаблону Справочник.ИмяСправочника.ДополнительныеРеквизиты (для документов аналогично).
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДопРеквизиты.Ссылка КАК Номенклатура,
| ДопРеквизиты.Значение КАК ЗначениеСвойства
|ИЗ
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты
|ГДЕ
| ДопРеквизиты.Свойство = &Свойство
| И ДопРеквизиты.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Свойство", СвойствоСсылка);
Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
ЗначениеРеквизита = Результат.ЗначениеСвойства;
КонецЕсли;
Если убрать условие по ссылке, одним запросом можно получить значения реквизита сразу для всех элементов справочника — это удобно для выгрузок и синхронизаций. Для нескольких свойств одновременно используйте условие Свойство В (&СписокСвойств) и группируйте результат по ссылке.
Способ 3: функции БСП (УправлениеСвойствами)
В конфигурациях на базе Библиотеки стандартных подсистем («Управление торговлей», «ERP», «Бухгалтерия предприятия» и других типовых) есть готовый программный интерфейс подсистемы «Свойства». Она сама определяет, где лежит значение — в табличной части реквизитов или в регистре сведений.
// Значение одного свойства
Значение = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаОбъект, СвойствоСсылка);
// Все дополнительные реквизиты и сведения объекта одним вызовом
СвойстваОбъекта = УправлениеСвойствами.СвойстваОбъекта(СсылкаНаОбъект, Истина, Истина);
Значения = УправлениеСвойствами.ЗначенияСвойств(СсылкаНаОбъект, Истина, Истина, СвойстваОбъекта);
Функция ЗначенияСвойств возвращает таблицу значений со строками «Свойство — Значение», что удобно для печатных форм и выгрузок. Параметры метода могут отличаться в зависимости от версии БСП, поэтому точную сигнатуру проверяйте в общем модуле УправлениеСвойствами вашей конфигурации.
Сравнение способов
Подходит для модуля объекта и формы. Требует ПолучитьОбъект(), медленно при массовом обходе.
Лучший вариант для выборок и отчётов. Требует знать имя таблицы объекта и ссылку на свойство.
Универсально для реквизитов и сведений, но работает только в конфигурациях с внедрённой БСП.
Как получить ссылку на свойство
Во всех способах нужна ссылка на элемент плана видов характеристик «ДополнительныеРеквизитыИСведения». Есть несколько вариантов её получения, и от надёжности этого шага зависит устойчивость всего кода.
- По наименованию —
НайтиПоНаименованию("Цвет", Истина). Просто, но ломается при переименовании реквизита пользователем. - По предопределённому имени — если свойство задано разработчиком как предопределённый элемент, обращение идёт через
ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ИмяСвойства. Самый надёжный вариант. - Через константу или параметр — ссылка на свойство сохраняется в настройках обработки, что позволяет администратору переназначить её без доработки кода.
Перед использованием проверяйте, что ссылка не пустая: Если НЕ ЗначениеЗаполнено(СвойствоСсылка) Тогда .... Иначе запрос просто не вернёт строк, и ошибку будет сложно локализовать.
- 1Определите, что читаете: дополнительный реквизит (табличная часть) или дополнительное сведение (регистр сведений)
- 2Получите ссылку на свойство из плана видов характеристик «ДополнительныеРеквизитыИСведения»
- 3Выберите способ: табличная часть для одиночного объекта, запрос для выборки, БСП для типовой конфигурации
- 4Выполните чтение и проверьте, что результат не пустой
- 5Проверьте тип значения перед использованием в расчётах
Проверка результата и типов значений
Дополнительный реквизит может иметь составной тип: строка, число, булево, дата или ссылка на справочник «ЗначенияСвойствОбъектов». Поэтому перед использованием значения стоит проверить его заполненность и тип — особенно если значение участвует в арифметике или сравнении.
Если ЗначениеЗаполнено(ЗначениеРеквизита) Тогда
Если ТипЗнч(ЗначениеРеквизита) = Тип("Число") Тогда
// безопасно использовать в расчётах
КонецЕсли;
КонецЕсли;
Отсутствие строки в табличной части и пустое значение в строке — разные ситуации. В первом случае реквизит вообще не заполнялся, во втором — заполнен пустым значением. Если для логики это принципиально, различайте результат Неопределено (строки нет) и пустое значение соответствующего типа.
Как проверить результат
ЗначениеЗаполнено(СвойствоСсылка) = Истина
Пустая ссылка — свойство не найдено по наименованию
НайтиСтроки вернул хотя бы одну строку
Пустой массив — реквизит не заполнялся или это дополнительное сведение
Значение ожидаемого типа и заполнено
Неопределено или значение другого типа — проверьте тип реквизита в настройках
Типичные ошибки и ограничения
Большинство проблем при чтении дополнительных реквизитов связано не с синтаксисом, а с непониманием модели хранения. Ниже — ситуации, которые чаще всего приводят к «пустому» результату или ошибкам выполнения.
Ещё одно ограничение: в запросах с соединениями таблица дополнительных реквизитов может порождать дубли строк основной таблицы, если у объекта несколько свойств. Соединяйте с условием по конкретному свойству или используйте левое соединение отдельно для каждого реквизита с псевдонимами.
Если значение дополнительного реквизита нужно часто в отчётах и отборах, рассмотрите перенос его в обычный реквизит конфигурации при доработке. Это упростит запросы и ускорит отборы, но потребует обновления конфигурации и переноса уже введённых значений.
FAQ
Чем дополнительный реквизит отличается от дополнительного сведения?
Реквизит хранится в табличной части объекта, виден на его форме как обычное поле и доступен для отборов в списках. Сведение хранится в регистре сведений «ДополнительныеСведения» и читается через отбор по объекту и свойству. Код для чтения разный, поэтому сначала уточните, как именно настроено поле в «Администрирование → Общие настройки → Дополнительные реквизиты и сведения».
Как получить значение дополнительного сведения программно?
Через менеджер записи или запрос к регистру сведений «ДополнительныеСведения» с отбором по полям «Объект» и «Свойство». В конфигурациях с БСП проще использовать УправлениеСвойствами.ЗначениеСвойства() — она сама определяет место хранения.
Почему запрос к таблице ДополнительныеРеквизиты возвращает пустой результат?
Наиболее вероятные причины: свойство не найдено и в параметр передана пустая ссылка; реквизит настроен как сведение и хранится в регистре; реквизит не входит в набор свойств для данного вида объектов; значение просто не заполнено у конкретного элемента. Проверяйте каждый пункт по очереди, начиная со ссылки на свойство.
Как получить значения сразу нескольких дополнительных реквизитов?
Одним запросом с условием «Свойство В (&СписокСвойств)» — в параметр передаётся массив ссылок. Результат группируется по ссылке на объект, а нужные свойства выбираются из строк выборки. В БСП для этого есть функция УправлениеСвойствами.ЗначенияСвойств().
Нужны ли особые права для чтения дополнительных реквизитов?
Да, применяются стандартные правила ролевого доступа: у пользователя должны быть права на чтение самого объекта и на план видов характеристик «ДополнительныеРеквизитыИСведения». В привилегированном модуле проверка прав отключается, что используют для служебных алгоритмов.
Можно ли изменить значение дополнительного реквизита программно?
Да: получите объект через ПолучитьОбъект(), найдите строку в табличной части «ДополнительныеРеквизиты» (или добавьте новую с нужным свойством), установите поле «Значение» и вызовите Записать(). Перед массовой записью проверяйте код на копии базы и выполняйте её в транзакции.
Что важно запомнить
Значения дополнительных реквизитов лежат в табличной части «ДополнительныеРеквизиты», а сведений — в регистре «ДополнительныеСведения». Для одиночного объекта читайте табличную часть, для выборок используйте запрос, в типовых конфигурациях — функции БСП УправлениеСвойствами. Всегда проверяйте ссылку на свойство и тип полученного значения.