Разработка и Конфигурация · 11 мин
Синтаксис запросов 1С: оператор ГДЕ и условия отбора
Как работает оператор ГДЕ в языке запросов 1С: условия, сравнения, ссылки, NULL, вложенные запросы, типичные ошибки и готовые примеры кода.
Оператор ГДЕ — основной инструмент отбора данных в языке запросов 1С. Он определяет, какие строки попадут в результат запроса, и напрямую влияет на производительность: правильно построенное условие позволяет использовать индексы и не читать лишние записи, а ошибка в условии способна замедлить запрос в десятки раз на больших таблицах.
Синтаксис языка запросов 1С во многом похож на SQL, но имеет важные отличия: условия пишутся на русском языке, поддерживаются специфические конструкции вроде «ССЫЛКА», «В ИЕРАРХИИ», «МЕЖДУ», а работа с пустыми ссылками и значениями NULL устроена иначе, чем в классических СУБД. Именно эти особенности чаще всего вызывают ошибки у начинающих разработчиков.
Ниже разобраны основные виды условий, параметризация, работа с NULL и датами, типичные ошибки и способы проверить корректность отбора до вывода результата пользователю.
Базовый синтаксис оператора ГДЕ
Секция ГДЕ располагается после указания источника данных (ИЗ) и до группировок, итогов и упорядочивания. Простейший запрос с отбором выглядит так:
ВЫБРАТЬ
Номенклатура.Ссылка,
Номенклатура.Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.ПометкаУдаления = ЛОЖЬ
Условие строится из полей таблицы, операторов сравнения и значений. Допустимые операторы сравнения: равно (=), не равно (<>), больше (>), меньше (<), больше или равно (>=), меньше или равно (<=). Логические значения записываются как ИСТИНА и ЛОЖЬ, строковые литералы — в двойных кавычках.
Несколько условий объединяются логическими операторами И, ИЛИ и НЕ. Приоритет стандартный: НЕ вычисляется первым, затем И, затем ИЛИ. Чтобы не зависеть от приоритета, всегда расставляйте скобки при смешивании И и ИЛИ — это самая частая причина «неправильно работающего» отбора.
ГДЕ
(Товары.Склад = &Склад И Товары.Количество > 0)
ИЛИ Товары.Резерв > 0
Параметры в условиях: почему нельзя подставлять строки напрямую
Правильный способ передать значение в условие — параметр с префиксом амперсанда: &ИмяПараметра. Параметр задаётся через метод УстановитьПараметр объекта Запрос до выполнения:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Номенклатура,
| СУММА(Продажи.Количество) КАК Количество
|ИЗ
| РегистрНакопления.Продажи КАК Продажи
|ГДЕ
| Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода
|СГРУППИРОВАТЬ ПО
| Продажи.Номенклатура";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));
Результат = Запрос.Выполнить();
Подстановка значений прямо в текст запроса через конкатенацию строк — грубая ошибка. Она ломает запрос на спецсимволах, мешает СУБД кэшировать план выполнения и создаёт риск некорректной интерпретации дат и чисел. Единственное оправданное исключение — динамическое изменение структуры запроса (например, имени таблицы), и даже там лучше использовать шаблоны с методом СтрЗаменить по строгому списку допустимых значений.
Специальные операторы условий
В и В ИЕРАРХИИ — отбор по списку и по группе
Оператор В проверяет вхождение значения в список. Список можно передать параметром-массивом или списком значений — платформа сама развернёт его в условие:
ГДЕ
Номенклатура.Ссылка В (&СписокТоваров)
Оператор В ИЕРАРХИИ отбирает элементы, входящие в указанную группу справочника с учётом всех вложенных подгрупп. Это удобно для отборов вида «все товары из раздела Электроника и его подразделов»:
ГДЕ
Номенклатура.Ссылка В ИЕРАРХИИ (&ГруппаТоваров)
ПОДОБНО — поиск по шаблону
Оператор ПОДОБНО работает как LIKE в SQL: символ % заменяет любую последовательность символов, символ _ — ровно один символ. Для поиска товаров, начинающихся с определённого текста:
ГДЕ
Номенклатура.Наименование ПОДОБНО &Шаблон
// параметр: Запрос.УстановитьПараметр("Шаблон", "Кабель%");
Учтите: условие ПОДОБНО с шаблоном, начинающимся с %, не может использовать индекс и приведёт к полному сканированию таблицы. На больших справочниках такие запросы выполняются заметно дольше — по возможности ограничивайте выборку дополнительными индексируемыми условиями.
МЕЖДУ и ССЫЛКА
Оператор МЕЖДУ проверяет попадание значения в диапазон включительно: Поле МЕЖДУ &Начало И &Конец эквивалентно Поле >= &Начало И Поле <= &Конец. Оператор ССЫЛКА проверяет, что поле ссылается на объект конкретного типа — полезно для полей составного типа:
ГДЕ
Документ.Контрагент ССЫЛКА Справочник.Контрагенты
Работа с NULL и пустыми значениями
NULL возникает в результатах запросов при левом соединении, когда в правой таблице не нашлось подходящей записи, а также в реквизитах составного типа, если значение не заполнено. Сравнение с NULL через = всегда даёт неопределённый результат — такая строка не попадёт в выборку. Проверять NULL нужно специальным оператором:
ГДЕ
Остатки.Количество ЕСТЬ NULL
Для замены NULL на конкретное значение используется функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). Типичный сценарий — вывести ноль вместо NULL при соединении номенклатуры с остатками:
ВЫБРАТЬ
Товары.Ссылка,
ЕСТЬNULL(Остатки.Количество, 0) КАК Остаток
ИЗ
Справочник.Номенклатура КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК Остатки
ПО Товары.Ссылка = Остатки.Номенклатура
Пустые ссылки, пустые строки и пустые даты — это не NULL. Для проверки пустой ссылки сравнивайте поле с ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка) или с параметром, в который передана пустая ссылка. Смешивание этих понятий — частая причина «пустого» результата запроса при формально верном синтаксисе.
Условия по датам и виртуальным таблицам
Даты в запросах сравниваются стандартными операторами, но есть нюанс с границами периода. Если параметр — дата без времени (начало дня), то условие Период <= &КонецДаты отсекает все записи после 00:00:00 конечного дня. Чтобы захватить весь день, передавайте конец дня или используйте строгое неравенство с началом следующего дня:
ГДЕ
Документ.Дата >= &НачалоДня
И Документ.Дата < &НачалоСледующегоДня
Литерал даты в тексте запроса задаётся функцией ДАТАВРЕМЯ(Год, Месяц, День, Час, Минута, Секунда), например ДАТАВРЕМЯ(2026, 1, 1) — это удобно для фиксированных границ в коде.
При работе с виртуальными таблицами регистров (Остатки, Обороты, СрезПоследних) условия эффективнее задавать в параметрах виртуальной таблицы, а не в секции ГДЕ. Параметры применяются до вычисления виртуальной таблицы, что сокращает объём обрабатываемых данных:
ИЗ
РегистрНакопления.ОстаткиТоваров.Остатки(&Период, Склад = &Склад) КАК Остатки
Где задавать условие
Отбор применяется до расчёта таблицы — быстрее на больших регистрах. Ограничение: доступны только поля, предусмотренные платформой для данной виртуальной таблицы.
Универсальный способ для любых полей и таблиц. На виртуальных таблицах без параметров может быть медленнее, так как отбор применяется после вычисления.
Для отбора правой таблицы при левом соединении: условие в ГДЕ превратит левое соединение во внутреннее и отфильтрует строки с NULL.
Проверка корректности отбора
Прежде чем встраивать запрос в рабочий код, проверьте его в консоли запросов или конструкторе запроса конфигуратора. Конструктор позволяет собрать условия визуально и сразу увидеть итоговый текст — это снижает риск синтаксических ошибок.
Проверяйте результат на граничных случаях: пустой параметр-список, параметр со значением NULL, дата без времени, отсутствие подходящих записей. Пустой массив в условии В (&Список) вернёт пустой результат — если для логики это означает «без отбора», условие нужно добавлять в текст запроса динамически, только когда список заполнен.
Как проверить результат
Совпадает с ожидаемым при ручной проверке по данным
Ноль строк или сильно больше ожидаемого — проверяйте скобки, NULL и границы дат
NULL обработаны через ЕСТЬNULL или ЕСТЬ NULL осознанно
Записи теряются из-за сравнения с NULL через равенство
Запрос выполняется быстро на реальном объёме данных
Заметная задержка — проверьте ПОДОБНО с %, условия по неиндексируемым полям и отсутствие параметров виртуальной таблицы
Частые вопросы по условиям ГДЕ
Как проверить, что поле не заполнено (пустая ссылка или пустая строка)?
Для ссылочных полей сравнивайте с ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка) или передавайте пустую ссылку параметром. Для строк — сравнение с пустой строкой "". Универсальный вариант для составных типов: Поле В (&ПустыеЗначения), где параметр — массив с пустыми значениями нужных типов, включая НЕОПРЕДЕЛЕНО при необходимости.
Почему условие В (&Список) возвращает пустой результат?
Чаще всего параметр не установлен, установлен пустым массивом или содержит значения другого типа (например, строки вместо ссылок). Проверьте тип и содержимое параметра перед выполнением. Если пустой список должен означать «без отбора», добавляйте условие в текст запроса только при заполненном списке.
Как отобрать записи за текущий месяц?
Передайте два параметра: начало месяца и начало следующего месяца, и используйте условие Период >= &Начало И Период < &Конец. Такой вариант корректно работает со временем в датах, в отличие от МЕЖДУ с концом месяца, где легко ошибиться с границей.
Можно ли использовать функции в условиях ГДЕ?
Да, доступны функции языка запросов: НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, ГОД, МЕСЯЦ, ПОДСТРОКА, ЕСТЬNULL и другие. Например: ГДЕ НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = &День. Учтите, что функция над индексируемым полем обычно отключает использование индекса.
Чем отличается ГДЕ от ИМЕЮЩИЕ?
ГДЕ фильтрует строки до группировки, ИМЕЮЩИЕ — после, по агрегатным значениям. Например, отобрать товары с суммарными продажами больше тысячи: СГРУППИРОВАТЬ ПО Номенклатура ИМЕЮЩИЕ СУММА(Количество) > 1000. В ИМЕЮЩИЕ нельзя использовать поля, по которым нет группировки или агрегации.
Как отладить сложное условие с несколькими И и ИЛИ?
Разбейте условие на части и проверяйте каждую отдельно в консоли запросов, затем собирайте обратно с явными скобками. Полезно временно вывести проверяемые поля в результат запроса — так видно, какие значения реально сравниваются, и где условие отсекает нужные строки.
Что важно запомнить
Оператор ГДЕ задаёт отбор строк запроса: используйте параметры вместо подстановки строк, проверяйте NULL только через ЕСТЬ NULL, группируйте И/ИЛИ скобками, даты сравнивайте с учётом времени, а для виртуальных таблиц регистров задавайте условия в параметрах — это быстрее и надёжнее.