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

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

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

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

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

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

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

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

Это важно понимать по двум причинам. Во-первых, обращение вида СправочникОбъект.МойДопРеквизит вызовет ошибку — такого поля у объекта нет. Во-вторых, у одного объекта может быть несколько дополнительных реквизитов, и искать нужный приходится по ссылке на элемент плана видов характеристик, а не по имени.

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

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

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

Для Каждого Строка Из Объект.ДополнительныеРеквизиты Цикл

Если Строка.Свойство = Свойство Тогда

Возврат Строка.Значение;

КонецЕсли;

КонецЦикла;

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

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

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

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

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

Учтите, что метод НайтиПоНаименованию ищет по точному совпадению и может вернуть не тот элемент, если в базе есть одноимённые свойства, созданные для разных наборов объектов (например, отдельно для «Номенклатуры» и «Контрагентов»). Проверяйте принадлежность свойства нужному набору.

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

Когда нужно получить значения дополнительного реквизита сразу для списка объектов — например, вывести колонку в динамический список или обработать тысячи элементов — перебор объектов в цикле неприемлем по производительности. Используйте запрос с левым соединением к табличной части.

ВЫБРАТЬ

Номенклатура.Ссылка КАК Номенклатура,

ДопРеквизиты.Значение КАК ЦветКорпуса

ИЗ

Справочник.Номенклатура КАК Номенклатура

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

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

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

Ключевой момент — условие на свойство должно стоять в секции ПО соединения, а не в секции ГДЕ. Если вынести его в ГДЕ, левое соединение фактически превратится во внутреннее, и объекты без заполненного реквизита выпадут из выборки.

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

Штатные функции БСП

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

Для получения значения конкретного свойства у одного объекта:

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

СсылкаНаОбъект, Свойство);

Для получения всех значений дополнительных реквизитов объекта одной таблицей:

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

СсылкаНаОбъект, Истина, Ложь);

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

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

Перебор табличной части

Подходит для одного объекта в модуле объекта или формы. Не годится для массовой обработки — каждый объект придётся читать целиком.

Запрос с соединением

Оптимален для списков и обработок большого объёма данных. Требует аккуратности с условиями соединения.

Функции БСП

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

Характеристики в СКД

Единственный корректный вариант для отчётов и динамических списков в типовых конфигурациях.

Дополнительные реквизиты в отчётах на СКД

В отчётах на системе компоновки данных соединять табличную часть вручную не нужно. В типовых конфигурациях для наборов данных настроен механизм характеристик: дополнительные реквизиты появляются в списке доступных полей отчёта как подчинённые поля ссылки, например «Номенклатура.Цвет корпуса».

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

Если вы пишете собственную схему компоновки для самописной конфигурации, механизм характеристик придётся настроить вручную на закладке «Характеристики» конструктора СКД. Без этой настройки дополнительные реквизиты в отчёте доступны не будут.

Дополнительные сведения: в чём отличие

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

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

ВЫБРАТЬ

ДопСведения.Значение

ИЗ

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

ГДЕ

ДопСведения.Объект = &Объект

И ДопСведения.Свойство = &Свойство

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

Работа с типами значений и проверка результата

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

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

Если реквизит не заполнен, перебор вернёт Неопределено, а запрос — пустое значение соответствующего типа или NULL при левом соединении. Обрабатывайте NULL функцией ЕСТЬNULL(ДопРеквизиты.Значение, ""), если пустое значение критично для дальнейшей логики.

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

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

Количество строк в итоговой выборке
Норма

Совпадает с количеством объектов, у части объектов значение пустое

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

Строк меньше, чем объектов — условие на свойство стоит в секции ГДЕ

Значение конкретного объекта
Норма

Совпадает с тем, что видно на закладке «Дополнительно» в форме объекта

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

Возвращается значение другого свойства — найден не тот элемент плана видов характеристик

Тип возвращаемого значения
Норма

Соответствует типу, заданному в настройках свойства

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

Возвращается ссылка на справочник значений свойств, а ожидалась строка — это свойство типа «Дополнительное значение»

Производительность и безопасные границы

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

Второй риск — модификация данных. Если вы не только читаете, но и записываете значения дополнительных реквизитов, помните: запись объекта через Записать() вызывает все обработчики событий объекта и может изменить связанные данные. Перед массовыми обработками записи обязательно делайте резервную копию или тестируйте обработку на копии базы.

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

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

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

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

Почему НайтиПоНаименованию возвращает не то свойство?

В плане видов характеристик может быть несколько свойств с одинаковым наименованием, созданных для разных наборов объектов. Дополнительно проверяйте набор свойств, к которому привязано найденное свойство, или ищите по уникальному имени для обмена.

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

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

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

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

Что вернёт запрос, если реквизит у объекта не заполнен?

При левом соединении поле значения будет NULL. Используйте функцию ЕСТЬNULL с подходящим значением по умолчанию, чтобы избежать проблем при сравнениях и выводе.

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

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

Итог

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

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