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