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