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

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

Как получить дополнительный реквизит справочника в 1С

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

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

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

Ниже разобраны рабочие способы: запрос к табличной части, программное чтение через объект, готовые функции БСП и обращение к свойству по имени. Код приведён для управляемых форм и обычного приложения — синтаксис в этой части одинаковый.

Как устроено хранение доп реквизитов

Когда администратор добавляет дополнительный реквизит к справочнику «Номенклатура», платформа не создаёт новую колонку в таблице справочника. Вместо этого в объекте появляется (или используется существующая) табличная часть ДополнительныеРеквизиты с колонками «Свойство» (ссылка на ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения) и «Значение».

Если же свойство добавлено как «дополнительное сведение», оно вообще не попадает в объект — значение пишется в регистр сведений «ДополнительныеСведения» с измерением «Объект» и «Свойство». Это принципиальная разница: сведение можно менять без записи самого объекта и без монопольного доступа к нему, но и читать его нужно из регистра.

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

Получение значения запросом

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

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

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

"ВЫБРАТЬ

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

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

|ИЗ

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

|ГДЕ

| НоменклатураДопРеквизиты.Свойство = &Свойство

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

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

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

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

ЗначениеДопРеквизита = Выборка.ЗначениеСвойства;

КонецЕсли;

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

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

"ВЫБРАТЬ

| ДополнительныеСведения.Значение

|ИЗ

| РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения

|ГДЕ

| ДополнительныеСведения.Объект = &Ссылка

| И ДополнительныеСведения.Свойство = &Свойство";

Чтение через объект справочника

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

ОбъектНоменклатуры = ЭлементСправочника.ПолучитьОбъект();

СтрокиСвойства = ОбъектНоменклатуры.ДополнительныеРеквизиты.НайтиСтроки(

Новый Структура("Свойство", СвойствоСсылка));

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

ЗначениеДопРеквизита = СтрокиСвойства[0].Значение;

Иначе

ЗначениеДопРеквизита = Неопределено; // свойство не заполнено

КонецЕсли;

Метод НайтиСтроки возвращает массив — даже если свойство одно, обращаться к значению нужно через нулевой элемент массива, предварительно проверив, что массив не пустой. Пропуск этой проверки — частая причина ошибки «Индекс находится за границами массива».

Получение свойства по имени

Чаще всего в коде известно не значение ссылки на свойство, а его наименование — например, «Цвет упаковки». Тогда ссылку нужно сначала найти:

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

.НайтиПоНаименованию("Цвет упаковки", Истина);

Если СвойствоСсылка.Пустая() Тогда

ВызватьИсключение "Свойство ""Цвет упаковки"" не найдено";

КонецЕсли;

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

Использование функций БСП

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

// Получить значения всех доп реквизитов объекта

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

// Получить значения конкретных свойств

МассивСвойств = Новый Массив;

МассивСвойств.Добавить(СвойствоСсылка);

ЗначенияСвойств = УправлениеСвойствами.ЗначенияСвойств(

ЭлементСправочника, Истина, Ложь, МассивСвойств);

Для Каждого Строка Из ЗначенияСвойств Цикл

// Строка.Свойство, Строка.Значение

КонецЦикла;

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

Выбор способа под задачу

Универсального «правильного» способа нет — выбор зависит от контекста: объём данных, наличие БСП, нужно ли менять объект.

Маршрут решения

Как выбрать способ

Нужно значение для одного или нескольких элементов, объект не изменяетсяИспользуйте запрос к табличной части ДополнительныеРеквизиты или к регистру ДополнительныеСведения
Объект уже получен для записи или измененияЧитайте через НайтиСтроки по табличной части объекта — без лишних обращений к базе
Конфигурация на БСП и код должен переживать обновленияИспользуйте УправлениеСвойствами.ЗначенияСвойств / СвойстваОбъекта
Нужно вывести доп реквизит в отчёт или динамический списокДобавьте соединение с табличной частью в запросе СКД либо используйте характеристики в консоли отчетов
Свойство добавлено как дополнительное сведениеЧитайте только из регистра сведений ДополнительныеСведения — в табличной части объекта его нет

Для отчётов на СКД есть нюанс: соединение с табличной частью по свойству требует передачи ссылки на свойство параметром, иначе при нескольких свойствах строки задублируются. Альтернатива — механизм характеристик в СКД, который автоматически подтягивает доп реквизиты как доступные поля.

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

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

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

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

Заполненное свойство
Норма

Запрос или НайтиСтроки возвращают значение нужного типа

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

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

Незаполненное свойство
Норма

Возвращается Неопределено или пустая выборка без ошибки

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

Исключение «Индекс за границами массива» — нет проверки Количество() > 0

Поиск свойства по имени
Норма

Найдено свойство из нужного набора реквизитов

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

Найдено одноимённое свойство другого справочника

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

Частые вопросы

Можно ли получить доп реквизит через точку, как обычный реквизит?

Нет. Дополнительные реквизиты не входят в состав метаданных справочника, платформа о них «не знает» на этапе компиляции. Обращение вида Ссылка.МойДопРеквизит вызовет ошибку. Используйте запрос, табличную часть объекта или функции БСП.

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

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

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

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

Что возвращается, если свойство у элемента не заполнено?

Строка в табличной части просто отсутствует, поэтому запрос вернёт пустую выборку, а НайтиСтроки — пустой массив. Код должен корректно обрабатывать этот случай: присваивать Неопределено или значение по умолчанию, а не обращаться к несуществующему элементу массива.

Как вывести доп реквизит в отчёт на СКД?

Два пути: добавить в запрос набора данных левое соединение с табличной частью ДополнительныеРеквизиты с отбором по конкретному свойству, либо использовать механизм характеристик СКД — тогда все доп реквизиты станут доступны пользователю как поля отчёта без изменения запроса.

Работает ли этот подход во внешних обработках и расширениях?

Да. Запросы к табличной части и регистру сведений, а также вызовы модулей БСП работают из внешних обработок и расширений без ограничений. Единственное условие — у пользователя должны быть права на чтение справочника и плана видов характеристик доп реквизитов.

Итог

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

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