К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как получить значение дополнительного реквизита в 1С 8.3 программно

Способы программного получения значений дополнительных реквизитов в 1С 8.3: табличная часть объекта, запрос, БСП. Примеры кода, проверка результата и типичные ошибки.

Дополнительные реквизиты в 1С 8.3 хранятся не в основной таблице объекта, а в отдельной табличной части «ДополнительныеРеквизиты», поэтому простое обращение через точку вида Справочник.Цвет не сработает. Чтобы получить значение, нужно либо прочитать эту табличную часть из объекта, либо выполнить запрос к таблице дополнительных реквизитов, либо воспользоваться механизмами Библиотеки стандартных подсистем (БСП), если она встроена в конфигурацию.

Выбор способа зависит от контекста: в модуле объекта удобнее работать напрямую с табличной частью, при обходе больших выборок быстрее запрос, а в типовых конфигурациях на базе БСП правильнее использовать готовые функции, которые учитывают и дополнительные сведения, и особенности хранения. Ниже разобраны все три подхода с примерами кода, проверкой результата и типичными ошибками.

Где физически хранятся значения дополнительных реквизитов

Механизм дополнительных реквизитов реализован через план видов характеристик «ДополнительныеРеквизитыИСведения». Каждый созданный в режиме предприятия реквизит (например, «Цвет» или «Гарантийный срок») — это элемент этого плана видов характеристик. Сами значения для конкретных объектов записываются в табличную часть «ДополнительныеРеквизиты» соответствующего справочника или документа, где каждая строка содержит ссылку на свойство и его значение.

Важно различать дополнительные реквизиты и дополнительные сведения. Реквизиты хранятся в табличной части объекта и доступны для отбора в списках, а сведения — в отдельном регистре сведений «ДополнительныеСведения». Код для их чтения отличается, и путаница между ними — одна из самых частых причин «пустого» результата.

Способ 1: чтение табличной части объекта

Самый прямой способ — получить объект методом ПолучитьОбъект() и найти нужную строку в табличной части «ДополнительныеРеквизиты» по ссылке на свойство. Подходит, когда объект уже открыт для чтения или изменения, например в обработчиках формы или модуля объекта.

Функция ПолучитьЗначениеДопРеквизита(СсылкаНаОбъект, СвойствоСсылка)

ОбъектДанных = СсылкаНаОбъект.ПолучитьОбъект();

ПараметрыОтбора = Новый Структура("Свойство", СвойствоСсылка);

НайденныеСтроки = ОбъектДанных.ДополнительныеРеквизиты.НайтиСтроки(ПараметрыОтбора);

Если НайденныеСтроки.Количество() > 0 Тогда

Возврат НайденныеСтроки[0].Значение;

Иначе

Возврат Неопределено;

КонецЕсли;

КонецФункции

Обратите внимание: ПолучитьОбъект() вычитывает объект из базы целиком, что при массовом обходе тысяч элементов даёт заметную нагрузку. Для пакетной обработки этот способ не подходит — используйте запрос.

Чтобы получить ссылку на свойство, найдите его в плане видов характеристик по наименованию:

СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения

.НайтиПоНаименованию("Гарантийный срок", Истина);

Способ 2: получение значения запросом

Запрос к таблице дополнительных реквизитов — оптимальный вариант для отчётов, обработок и выборок по многим объектам. Таблица называется по шаблону Справочник.ИмяСправочника.ДополнительныеРеквизиты (для документов аналогично).

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДопРеквизиты.Ссылка КАК Номенклатура,

| ДопРеквизиты.Значение КАК ЗначениеСвойства

|ИЗ

| Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты

|ГДЕ

| ДопРеквизиты.Свойство = &Свойство

| И ДопРеквизиты.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Свойство", СвойствоСсылка);

Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);

Результат = Запрос.Выполнить().Выбрать();

Если Результат.Следующий() Тогда

ЗначениеРеквизита = Результат.ЗначениеСвойства;

КонецЕсли;

Если убрать условие по ссылке, одним запросом можно получить значения реквизита сразу для всех элементов справочника — это удобно для выгрузок и синхронизаций. Для нескольких свойств одновременно используйте условие Свойство В (&СписокСвойств) и группируйте результат по ссылке.

Способ 3: функции БСП (УправлениеСвойствами)

В конфигурациях на базе Библиотеки стандартных подсистем («Управление торговлей», «ERP», «Бухгалтерия предприятия» и других типовых) есть готовый программный интерфейс подсистемы «Свойства». Она сама определяет, где лежит значение — в табличной части реквизитов или в регистре сведений.

// Значение одного свойства

Значение = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаОбъект, СвойствоСсылка);

// Все дополнительные реквизиты и сведения объекта одним вызовом

СвойстваОбъекта = УправлениеСвойствами.СвойстваОбъекта(СсылкаНаОбъект, Истина, Истина);

Значения = УправлениеСвойствами.ЗначенияСвойств(СсылкаНаОбъект, Истина, Истина, СвойстваОбъекта);

Функция ЗначенияСвойств возвращает таблицу значений со строками «Свойство — Значение», что удобно для печатных форм и выгрузок. Параметры метода могут отличаться в зависимости от версии БСП, поэтому точную сигнатуру проверяйте в общем модуле УправлениеСвойствами вашей конфигурации.

Сравнение способов

Табличная часть объекта

Подходит для модуля объекта и формы. Требует ПолучитьОбъект(), медленно при массовом обходе.

Запрос к таблице

Лучший вариант для выборок и отчётов. Требует знать имя таблицы объекта и ссылку на свойство.

Функции БСП

Универсально для реквизитов и сведений, но работает только в конфигурациях с внедрённой БСП.

Как получить ссылку на свойство

Во всех способах нужна ссылка на элемент плана видов характеристик «ДополнительныеРеквизитыИСведения». Есть несколько вариантов её получения, и от надёжности этого шага зависит устойчивость всего кода.

  • По наименованию — НайтиПоНаименованию("Цвет", Истина). Просто, но ломается при переименовании реквизита пользователем.
  • По предопределённому имени — если свойство задано разработчиком как предопределённый элемент, обращение идёт через ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ИмяСвойства. Самый надёжный вариант.
  • Через константу или параметр — ссылка на свойство сохраняется в настройках обработки, что позволяет администратору переназначить её без доработки кода.

Перед использованием проверяйте, что ссылка не пустая: Если НЕ ЗначениеЗаполнено(СвойствоСсылка) Тогда .... Иначе запрос просто не вернёт строк, и ошибку будет сложно локализовать.

Порядок действий
  1. 1
    Определите, что читаете: дополнительный реквизит (табличная часть) или дополнительное сведение (регистр сведений)
  2. 2
    Получите ссылку на свойство из плана видов характеристик «ДополнительныеРеквизитыИСведения»
  3. 3
    Выберите способ: табличная часть для одиночного объекта, запрос для выборки, БСП для типовой конфигурации
  4. 4
    Выполните чтение и проверьте, что результат не пустой
  5. 5
    Проверьте тип значения перед использованием в расчётах

Проверка результата и типов значений

Дополнительный реквизит может иметь составной тип: строка, число, булево, дата или ссылка на справочник «ЗначенияСвойствОбъектов». Поэтому перед использованием значения стоит проверить его заполненность и тип — особенно если значение участвует в арифметике или сравнении.

Если ЗначениеЗаполнено(ЗначениеРеквизита) Тогда

Если ТипЗнч(ЗначениеРеквизита) = Тип("Число") Тогда

// безопасно использовать в расчётах

КонецЕсли;

КонецЕсли;

Отсутствие строки в табличной части и пустое значение в строке — разные ситуации. В первом случае реквизит вообще не заполнялся, во втором — заполнен пустым значением. Если для логики это принципиально, различайте результат Неопределено (строки нет) и пустое значение соответствующего типа.

Контрольные точки

Как проверить результат

Ссылка на свойство
Норма

ЗначениеЗаполнено(СвойствоСсылка) = Истина

Тревожный признак

Пустая ссылка — свойство не найдено по наименованию

Строка в табличной части
Норма

НайтиСтроки вернул хотя бы одну строку

Тревожный признак

Пустой массив — реквизит не заполнялся или это дополнительное сведение

Значение
Норма

Значение ожидаемого типа и заполнено

Тревожный признак

Неопределено или значение другого типа — проверьте тип реквизита в настройках

Типичные ошибки и ограничения

Большинство проблем при чтении дополнительных реквизитов связано не с синтаксисом, а с непониманием модели хранения. Ниже — ситуации, которые чаще всего приводят к «пустому» результату или ошибкам выполнения.

Типичные ошибки
01
Обращение Справочник.Цвет через точку — дополнительный реквизит не является полем объекта, возникает ошибка «Поле не обнаружено»
02
Поиск значения в табличной части, когда настроено дополнительное сведение — значения хранятся в регистре «ДополнительныеСведения», и табличная часть всегда пуста
03
Поиск свойства по наименованию без проверки результата — после переименования реквизита код молча возвращает пустоту
04
ПолучитьОбъект() в цикле по тысячам элементов — резкое падение производительности и блокировки
05
Игнорирование типа значения — строка «10» вместо числа 10 ломает сравнения и арифметику

Ещё одно ограничение: в запросах с соединениями таблица дополнительных реквизитов может порождать дубли строк основной таблицы, если у объекта несколько свойств. Соединяйте с условием по конкретному свойству или используйте левое соединение отдельно для каждого реквизита с псевдонимами.

Если значение дополнительного реквизита нужно часто в отчётах и отборах, рассмотрите перенос его в обычный реквизит конфигурации при доработке. Это упростит запросы и ускорит отборы, но потребует обновления конфигурации и переноса уже введённых значений.
ПЗ
Практическое замечание

FAQ

Чем дополнительный реквизит отличается от дополнительного сведения?

Реквизит хранится в табличной части объекта, виден на его форме как обычное поле и доступен для отборов в списках. Сведение хранится в регистре сведений «ДополнительныеСведения» и читается через отбор по объекту и свойству. Код для чтения разный, поэтому сначала уточните, как именно настроено поле в «Администрирование → Общие настройки → Дополнительные реквизиты и сведения».

Как получить значение дополнительного сведения программно?

Через менеджер записи или запрос к регистру сведений «ДополнительныеСведения» с отбором по полям «Объект» и «Свойство». В конфигурациях с БСП проще использовать УправлениеСвойствами.ЗначениеСвойства() — она сама определяет место хранения.

Почему запрос к таблице ДополнительныеРеквизиты возвращает пустой результат?

Наиболее вероятные причины: свойство не найдено и в параметр передана пустая ссылка; реквизит настроен как сведение и хранится в регистре; реквизит не входит в набор свойств для данного вида объектов; значение просто не заполнено у конкретного элемента. Проверяйте каждый пункт по очереди, начиная со ссылки на свойство.

Как получить значения сразу нескольких дополнительных реквизитов?

Одним запросом с условием «Свойство В (&СписокСвойств)» — в параметр передаётся массив ссылок. Результат группируется по ссылке на объект, а нужные свойства выбираются из строк выборки. В БСП для этого есть функция УправлениеСвойствами.ЗначенияСвойств().

Нужны ли особые права для чтения дополнительных реквизитов?

Да, применяются стандартные правила ролевого доступа: у пользователя должны быть права на чтение самого объекта и на план видов характеристик «ДополнительныеРеквизитыИСведения». В привилегированном модуле проверка прав отключается, что используют для служебных алгоритмов.

Можно ли изменить значение дополнительного реквизита программно?

Да: получите объект через ПолучитьОбъект(), найдите строку в табличной части «ДополнительныеРеквизиты» (или добавьте новую с нужным свойством), установите поле «Значение» и вызовите Записать(). Перед массовой записью проверяйте код на копии базы и выполняйте её в транзакции.

Итог

Что важно запомнить

Значения дополнительных реквизитов лежат в табличной части «ДополнительныеРеквизиты», а сведений — в регистре «ДополнительныеСведения». Для одиночного объекта читайте табличную часть, для выборок используйте запрос, в типовых конфигурациях — функции БСП УправлениеСвойствами. Всегда проверяйте ссылку на свойство и тип полученного значения.