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