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