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

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

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

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

Дополнительные реквизиты в 1С хранятся не в основной таблице объекта, а в отдельных табличных частях и регистрах сведений. Из-за этого простой запрос вида «ВЫБРАТЬ Ссылка, Цвет Из Справочник.Номенклатура» не сработает — система выдаст ошибку «Поле не найдено». Чтобы получить значения дополнительных реквизитов, нужно обратиться к табличной части объекта или к регистру сведений «Дополнительные сведения» и связать их с основной таблицей.

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

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

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

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

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

Запрос к табличной части «ДополнительныеРеквизиты»

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

bsl
ВЫБРАТЬ
	Номенклатура.Ссылка КАК Номенклатура,
	ДопРеквизиты.Значение КАК Цвет
ИЗ
	Справочник.Номенклатура КАК Номенклатура
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты
		ПО Номенклатура.Ссылка = ДопРеквизиты.Ссылка
			И ДопРеквизиты.Свойство = &Свойство

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

Обратите внимание: условие по свойству помещено в секцию соединения (ПО), а не в ГДЕ. Если вынести его в ГДЕ, левое соединение превратится фактически во внутреннее — все объекты без заполненного реквизита выпадут из выборки. Это одна из самых частых причин «пропавших» строк.

Как вывести несколько свойств в одном запросе

Если нужно получить несколько реквизитов одним запросом, есть два подхода. Первый — несколько левых соединений с одной и той же табличной частью под разными псевдонимами, каждое со своим свойством. Второй — одно соединение с выборкой всех пар «Свойство — Значение» и последующая развертка в сводной таблице или обработка результата в коде.

bsl
ВЫБРАТЬ
	Номенклатура.Ссылка КАК Номенклатура,
	РеквизитЦвет.Значение КАК Цвет,
	РеквизитРазмер.Значение КАК Размер
ИЗ
	Справочник.Номенклатура КАК Номенклатура
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК РеквизитЦвет
		ПО Номенклатура.Ссылка = РеквизитЦвет.Ссылка
			И РеквизитЦвет.Свойство = &СвойствоЦвет
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК РеквизитРазмер
		ПО Номенклатура.Ссылка = РеквизитРазмер.Ссылка
			И РеквизитРазмер.Свойство = &СвойствоРазмер

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

Запрос к регистру сведений «ДополнительныеСведения»

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

bsl
ВЫБРАТЬ
	Номенклатура.Ссылка КАК Номенклатура,
	ДопСведения.Значение КАК Производитель
ИЗ
	Справочник.Номенклатура КАК Номенклатура
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСведения
		ПО Номенклатура.Ссылка = ДопСведения.Объект
			И ДопСведения.Свойство = &Свойство

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

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

Как найти ссылку на свойство по имени

Для передачи параметра «Свойство» нужна ссылка на элемент плана видов характеристик «ДополнительныеРеквизитыИСведения». Простейший способ — найти по наименованию:

bsl
Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Цвет", Истина);

Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Свойство", Свойство);
Результат = Запрос.Выполнить().Выгрузить();

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

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

Использование в СКД и динамических списках

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

В динамических списках прямое соединение с табличной частью «ДополнительныеРеквизиты» работает, но ухудшает производительность на больших таблицах и может ломать стандартные механизмы отбора. Если требуется только отбор по значению свойства, часто проще использовать произвольный запрос с вложенным отбором: «Ссылка В (ВЫБРАТЬ Ссылка ИЗ ...ДополнительныеРеквизиты ГДЕ Свойство = &Свойство И Значение = &Значение)».

Способы получения значений

Соединение с табличной частью

Подходит для дополнительных реквизитов; простой и быстрый запрос, но требует отдельного соединения на каждое свойство.

Соединение с регистром ДополнительныеСведения

Подходит для дополнительных сведений; регистр индексирован по объекту и свойству, работает быстро даже на больших объёмах.

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

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

Обход объектов в коде

Подходит для разовых задач на малых объёмах; на тысячах элементов работает значительно медленнее запроса.

Производительность и ограничения

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

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

Ещё одно ограничение — тип значения. Поле «Значение» имеет составной тип (характеристика плана видов характеристик), поэтому сравнения и сортировки по нему могут работать медленнее и не всегда поддерживают агрегатные функции. Если по значению нужен отбор с приведением типа, используйте ВЫРАЗИТЬ(... КАК ...) явно.

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

Проверка результата и отладка

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

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

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

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

Количество строк результата
Норма

Равно числу объектов основной выборки

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

Строк больше — дубли из-за соединения без отбора по свойству

Значение свойства
Норма

Заполнено у объектов, где реквизит задан в карточке

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

NULL у всех строк — свойство не найдено или не тот источник хранения

Объекты без реквизита
Норма

Присутствуют в выборке с NULL при левом соединении

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

Пропали — условие по свойству вынесено в ГДЕ

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

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

Нет. Дополнительный реквизит не является полем основной таблицы объекта, поэтому конструкция «ВЫБРАТЬ Номенклатура.МойРеквизит» вызовет ошибку «Поле не найдено». Значение доступно только через соединение с табличной частью «ДополнительныеРеквизиты» или через характеристики в СКД.

Чем запрос к табличной части отличается от запроса к регистру «ДополнительныеСведения»?

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

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

Используйте механизм характеристик СКД: в наборе данных укажите источник характеристик (план видов характеристик «ДополнительныеРеквизитыИСведения») и источник значений (табличную часть или регистр). Тогда платформа автоматически добавит в отчёт все доступные свойства без перечисления их в тексте запроса.

Почему запрос возвращает NULL, хотя реквизит в карточке заполнен?

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

Как отобрать объекты по значению дополнительного реквизита?

Используйте вложенный запрос: «ГДЕ Ссылка В (ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура.ДополнительныеРеквизиты ГДЕ Свойство = &Свойство И Значение = &Значение)». Это быстрее соединения и не порождает дублей, так как фильтрует только основную таблицу.

Влияет ли количество соединений на скорость запроса?

Да. Каждое соединение с табличной частью — это отдельное чтение данных. На больших справочниках запрос с пятью и более соединениями может работать заметно медленно. Оптимизация: сначала отобрать нужные ссылки во временную таблицу, а соединения выполнять уже с ней.

Итог

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

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