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

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

Условие ГДЕ в запросе 1С: отбор по значению

Как использовать условие ГДЕ в запросах 1С: отбор по значению, параметры, операторы сравнения, В ИЕРАРХИИ, ПОДОБНО. Примеры кода и типичные ошибки.

Условие ГДЕ (WHERE) — основной инструмент отбора данных в языке запросов 1С. Оно позволяет выбрать из таблицы только те строки, где значение поля соответствует заданному критерию: равно конкретному параметру, входит в список, попадает в диапазон дат или подчинено элементу иерархии.

Без секции ГДЕ запрос вернёт все записи таблицы, что почти всегда избыточно и медленно. Правильно сформулированное условие сокращает объём выборки в десятки раз и снимает нагрузку с сервера. Поэтому умение задавать отбор по значению — базовый навык разработчика 1С, отчётовщика и администратора, работающего с консолью запросов.

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

Базовый синтаксис условия ГДЕ

Секция ГДЕ располагается после указания источника данных и перед группировкой или упорядочиванием. В простейшем виде условие сравнивает поле таблицы с параметром:

ВЫБРАТЬ

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

Номенклатура.Наименование

ИЗ

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

ГДЕ

Номенклатура.Артикул = &Артикул

Параметр объявляется символом амперсанда и заполняется перед выполнением запроса через метод Запрос.УстановитьПараметр("Артикул", "Т-100"). Всегда используйте параметры, а не конкатенацию строк запроса: подстановка текста напрямую создаёт риск ошибок с кавычками и ломает план выполнения запроса.

Условия комбинируются логическими операторами И, ИЛИ, НЕ. При смешивании И и ИЛИ обязательно ставьте скобки: приоритет И выше, и без скобок логика отбора может оказаться не той, что вы ожидали.

Отбор по равенству и сравнение значений

Оператор равенства подходит для точного совпадения: ссылки, артикула, кода, булева признака. Для чисел и дат применяются операторы сравнения: больше, меньше, больше или равно, меньше или равно, не равно.

ГДЕ

ПоступлениеТоваров.СуммаДокумента >= &МинимальнаяСумма

И ПоступлениеТоваров.Проведен = ИСТИНА

Частая ситуация — отбор по ссылке на элемент справочника. Параметру присваивается ссылка, полученная через Справочники.Контрагенты.НайтиПоКоду(...) или переданная из формы. Сравнивать ссылку со строковым представлением нельзя: типы не совпадут, и условие никогда не выполнится.

Оператор «не равно» (<>) требует осторожности со значениями NULL. Если поле может содержать NULL (например, результат левого соединения), сравнение «поле <> значение» для таких строк вернёт не ИСТИНУ, а NULL, и строка выпадет из выборки. Добавляйте явную обработку: ИЛИ Поле ЕСТЬ NULL.

Отбор по списку значений: оператор В

Когда нужно выбрать строки, где поле равно одному из нескольких значений, используется оператор В со списком или параметром-массивом:

ГДЕ

Реализация.Организация В (&СписокОрганизаций)

В параметр передаётся массив или список значений: Запрос.УстановитьПараметр("СписокОрганизаций", МассивОрганизаций). Это удобнее, чем цепочка условий через ИЛИ, и работает быстрее, потому что оптимизатор СУБД преобразует список в один предикат.

Оператор В принимает и вложенный запрос: В (ВЫБРАТЬ Контрагент ИЗ ...). Такой приём полезен, когда список отбора сам вычисляется из базы. Обратный вариант — НЕ В — исключает перечисленные значения.

Способы отбора по нескольким значениям

В (&Массив)

Оптимально для списка из десятков значений; параметр передаётся из кода, легко поддерживать

Цепочка ИЛИ

Допустимо для 2–3 фиксированных значений; при росте списка текст запроса раздувается

В (вложенный запрос)

Когда список вычисляется из базы; следите за производительностью вложенного запроса

Условия по датам и периодам

Отбор по дате — самый частый сценарий в учётных запросах. Для периода используется либо пара сравнений, либо оператор МЕЖДУ:

ГДЕ

Заказ.Дата МЕЖДУ &НачалоПериода И &КонецПериода

Критичный нюанс: дата в 1С хранится с точностью до секунды. Если передать в параметр конца периода дату без времени, она будет равна началу дня, и документы за весь последний день выпадут из выборки. Используйте КонецДня(Дата) при формировании параметра или функцию КОНЕЦПЕРИОДА(&Дата, ДЕНЬ) прямо в тексте запроса.

Для виртуальных таблиц регистров (Остатки, Обороты) отбор по периоду лучше задавать в параметрах виртуальной таблицы, а не в секции ГДЕ — тогда СУБД отфильтрует данные до соединения, что заметно быстрее.

Отбор по строкам: ПОДОБНО и работа с текстом

Для поиска по части строки применяется оператор ПОДОБНО с шаблоном. Символ процента заменяет любую последовательность символов, подчёркивание — один символ:

ГДЕ

Контрагенты.Наименование ПОДОБНО &ШаблонПоиска

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

Учтите, что ПОДОБНО чувствительно к регистру в зависимости от настроек СУБД. Для регистронезависимого поиска надёжнее привести обе стороны к одному регистру через ВРЕГ() или НРЕГ(), понимая, что это тоже отключает индекс.

Отбор по иерархии: В ИЕРАРХИИ

Справочники в 1С часто иерархические: группа «Электроника» содержит подгруппы и элементы. Чтобы выбрать все элементы, входящие в группу на любом уровне вложенности, используется оператор В ИЕРАРХИИ:

ГДЕ

Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)

Параметру присваивается ссылка на группу. Отбор сработает и для элементов, лежащих непосредственно в группе, и для элементов вложенных подгрупп. Тот же оператор работает в параметрах виртуальных таблиц регистров, где поле имеет ссылочный тип.

Если параметр не задан или равен пустой ссылке, условие не выполнится ни для одной строки. Когда отбор по группе опционален, оборачивайте его в конструкцию вида (&Группа = НЕОПРЕДЕЛЕНО ИЛИ Ссылка В ИЕРАРХИИ(&Группа)) либо формируйте текст запроса динамически.

Как проверить новое условие ГДЕ
  1. 1
    Откройте консоль запросов и выполните запрос без условия — зафиксируйте общее число строк
  2. 2
    Добавьте условие и задайте параметр заведомо существующим значением
  3. 3
    Сравните результат: должны отобраться только ожидаемые строки
  4. 4
    Проверьте граничные случаи: пустой параметр, значение с NULL, граница периода
  5. 5
    Замерьте время выполнения на рабочей копии базы, если таблица большая

Типичные ошибки и ограничения

Больше всего проблем доставляет несовпадение типов: строка вместо ссылки, число вместо строки, дата без времени. Запрос при этом не падает с ошибкой — он просто возвращает пустой результат, и причину приходится искать вручную. Проверяйте тип параметра через отладчик перед выполнением.

Вторая группа ошибок — логическая: отсутствие скобок при смешении И/ИЛИ, забытый ЕСТЬ NULL, условие по полю соединённой таблицы, обнуляющее эффект левого соединения. Если условие по правой таблице поместить в ГДЕ, левое соединение фактически превращается во внутреннее; переносите такие условия в секцию ПО соединения.

Наконец, производительность: функции над полем в условии (ВРЕГ, ПОДСТРОКА, ГОД) отключают использование индекса. По возможности преобразуйте параметр, а не поле, либо переносите вычисления на этап подготовки данных.

Типичные ошибки
01
Передача строки вместо ссылки — условие никогда не выполняется, результат пустой
02
Дата конца периода без времени — выпадает последний день выборки
03
Условие по правой таблице левого соединения в ГДЕ — теряются строки с NULL
04
Смешение И и ИЛИ без скобок — логика отбора искажается
05
ПОДОБНО с ведущим % на большой таблице — полное сканирование и медленный запрос

FAQ

Чем ГДЕ отличается от ИМЕЮЩИЕ?

ГДЕ фильтрует строки до группировки, а ИМЕЮЩИЕ — после неё и применяется к агрегатным результатам, например «СУММА(Количество) > 100». Поля без агрегатов фильтруйте через ГДЕ — это быстрее.

Можно ли использовать несколько условий ГДЕ в одном запросе?

Секция ГДЕ одна, но внутри неё условия объединяются операторами И, ИЛИ, НЕ в произвольной комбинации со скобками. Писать ГДЕ дважды нельзя — будет синтаксическая ошибка.

Как сделать условие необязательным?

Используйте приём «&Параметр = НЕОПРЕДЕЛЕНО ИЛИ Поле = &Параметр» и передавайте НЕОПРЕДЕЛЕНО, когда отбор не нужен. Альтернатива — динамическая сборка текста запроса или схема СКД, где отборы отключаются настройками.

Почему В ИЕРАРХИИ не находит элементы группы?

Проверьте, что параметру присвоена именно ссылка на группу, а не на элемент или код. Также убедитесь, что справочник действительно иерархический с видом иерархии «Список подчинённых» — иначе оператор неприменим.

Как отобрать документы только с заполненным полем?

Для ссылочных полей сравните с пустой ссылкой: «Поле <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)». Для строк — «Поле <> ""». Если поле может быть NULL, добавьте «И НЕ Поле ЕСТЬ NULL».

Итог

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

Условие ГДЕ фильтрует строки по значению поля через параметры и операторы =, В, МЕЖДУ, ПОДОБНО, В ИЕРАРХИИ. Передавайте значения параметрами, следите за типами и временем в датах, обрабатывайте NULL и не применяйте функции к индексированным полям.