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

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

Синтаксис запросов 1С: оператор ГДЕ и условия отбора

Как работает оператор ГДЕ в языке запросов 1С: условия, сравнения, ссылки, NULL, вложенные запросы, типичные ошибки и готовые примеры кода.

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

Синтаксис языка запросов 1С во многом похож на SQL, но имеет важные отличия: условия пишутся на русском языке, поддерживаются специфические конструкции вроде «ССЫЛКА», «В ИЕРАРХИИ», «МЕЖДУ», а работа с пустыми ссылками и значениями NULL устроена иначе, чем в классических СУБД. Именно эти особенности чаще всего вызывают ошибки у начинающих разработчиков.

Ниже разобраны основные виды условий, параметризация, работа с NULL и датами, типичные ошибки и способы проверить корректность отбора до вывода результата пользователю.

Базовый синтаксис оператора ГДЕ

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

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

Номенклатура.ПометкаУдаления = ЛОЖЬ

Условие строится из полей таблицы, операторов сравнения и значений. Допустимые операторы сравнения: равно (=), не равно (<>), больше (>), меньше (<), больше или равно (>=), меньше или равно (<=). Логические значения записываются как ИСТИНА и ЛОЖЬ, строковые литералы — в двойных кавычках.

Несколько условий объединяются логическими операторами И, ИЛИ и НЕ. Приоритет стандартный: НЕ вычисляется первым, затем И, затем ИЛИ. Чтобы не зависеть от приоритета, всегда расставляйте скобки при смешивании И и ИЛИ — это самая частая причина «неправильно работающего» отбора.

ГДЕ

(Товары.Склад = &Склад И Товары.Количество > 0)

ИЛИ Товары.Резерв > 0

Параметры в условиях: почему нельзя подставлять строки напрямую

Правильный способ передать значение в условие — параметр с префиксом амперсанда: &ИмяПараметра. Параметр задаётся через метод УстановитьПараметр объекта Запрос до выполнения:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Продажи.Номенклатура,

| СУММА(Продажи.Количество) КАК Количество

|ИЗ

| РегистрНакопления.Продажи КАК Продажи

|ГДЕ

| Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода

|СГРУППИРОВАТЬ ПО

| Продажи.Номенклатура";

Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));

Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));

Результат = Запрос.Выполнить();

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

Специальные операторы условий

В и В ИЕРАРХИИ — отбор по списку и по группе

Оператор В проверяет вхождение значения в список. Список можно передать параметром-массивом или списком значений — платформа сама развернёт его в условие:

ГДЕ

Номенклатура.Ссылка В (&СписокТоваров)

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

ГДЕ

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

ПОДОБНО — поиск по шаблону

Оператор ПОДОБНО работает как LIKE в SQL: символ % заменяет любую последовательность символов, символ _ — ровно один символ. Для поиска товаров, начинающихся с определённого текста:

ГДЕ

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

// параметр: Запрос.УстановитьПараметр("Шаблон", "Кабель%");

Учтите: условие ПОДОБНО с шаблоном, начинающимся с %, не может использовать индекс и приведёт к полному сканированию таблицы. На больших справочниках такие запросы выполняются заметно дольше — по возможности ограничивайте выборку дополнительными индексируемыми условиями.

МЕЖДУ и ССЫЛКА

Оператор МЕЖДУ проверяет попадание значения в диапазон включительно: Поле МЕЖДУ &Начало И &Конец эквивалентно Поле >= &Начало И Поле <= &Конец. Оператор ССЫЛКА проверяет, что поле ссылается на объект конкретного типа — полезно для полей составного типа:

ГДЕ

Документ.Контрагент ССЫЛКА Справочник.Контрагенты

Работа с NULL и пустыми значениями

NULL возникает в результатах запросов при левом соединении, когда в правой таблице не нашлось подходящей записи, а также в реквизитах составного типа, если значение не заполнено. Сравнение с NULL через = всегда даёт неопределённый результат — такая строка не попадёт в выборку. Проверять NULL нужно специальным оператором:

ГДЕ

Остатки.Количество ЕСТЬ NULL

Для замены NULL на конкретное значение используется функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). Типичный сценарий — вывести ноль вместо NULL при соединении номенклатуры с остатками:

ВЫБРАТЬ

Товары.Ссылка,

ЕСТЬNULL(Остатки.Количество, 0) КАК Остаток

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК Остатки

ПО Товары.Ссылка = Остатки.Номенклатура

Пустые ссылки, пустые строки и пустые даты — это не NULL. Для проверки пустой ссылки сравнивайте поле с ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка) или с параметром, в который передана пустая ссылка. Смешивание этих понятий — частая причина «пустого» результата запроса при формально верном синтаксисе.

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

Условия по датам и виртуальным таблицам

Даты в запросах сравниваются стандартными операторами, но есть нюанс с границами периода. Если параметр — дата без времени (начало дня), то условие Период <= &КонецДаты отсекает все записи после 00:00:00 конечного дня. Чтобы захватить весь день, передавайте конец дня или используйте строгое неравенство с началом следующего дня:

ГДЕ

Документ.Дата >= &НачалоДня

И Документ.Дата < &НачалоСледующегоДня

Литерал даты в тексте запроса задаётся функцией ДАТАВРЕМЯ(Год, Месяц, День, Час, Минута, Секунда), например ДАТАВРЕМЯ(2026, 1, 1) — это удобно для фиксированных границ в коде.

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

ИЗ

РегистрНакопления.ОстаткиТоваров.Остатки(&Период, Склад = &Склад) КАК Остатки

Где задавать условие

Параметры виртуальной таблицы

Отбор применяется до расчёта таблицы — быстрее на больших регистрах. Ограничение: доступны только поля, предусмотренные платформой для данной виртуальной таблицы.

Секция ГДЕ

Универсальный способ для любых полей и таблиц. На виртуальных таблицах без параметров может быть медленнее, так как отбор применяется после вычисления.

Условие соединения (ПО)

Для отбора правой таблицы при левом соединении: условие в ГДЕ превратит левое соединение во внутреннее и отфильтрует строки с NULL.

Проверка корректности отбора

Прежде чем встраивать запрос в рабочий код, проверьте его в консоли запросов или конструкторе запроса конфигуратора. Конструктор позволяет собрать условия визуально и сразу увидеть итоговый текст — это снижает риск синтаксических ошибок.

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

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

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

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

Совпадает с ожидаемым при ручной проверке по данным

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

Ноль строк или сильно больше ожидаемого — проверяйте скобки, NULL и границы дат

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

NULL обработаны через ЕСТЬNULL или ЕСТЬ NULL осознанно

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

Записи теряются из-за сравнения с NULL через равенство

Скорость выполнения
Норма

Запрос выполняется быстро на реальном объёме данных

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

Заметная задержка — проверьте ПОДОБНО с %, условия по неиндексируемым полям и отсутствие параметров виртуальной таблицы

Частые вопросы по условиям ГДЕ

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

Для ссылочных полей сравнивайте с ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка) или передавайте пустую ссылку параметром. Для строк — сравнение с пустой строкой "". Универсальный вариант для составных типов: Поле В (&ПустыеЗначения), где параметр — массив с пустыми значениями нужных типов, включая НЕОПРЕДЕЛЕНО при необходимости.

Почему условие В (&Список) возвращает пустой результат?

Чаще всего параметр не установлен, установлен пустым массивом или содержит значения другого типа (например, строки вместо ссылок). Проверьте тип и содержимое параметра перед выполнением. Если пустой список должен означать «без отбора», добавляйте условие в текст запроса только при заполненном списке.

Как отобрать записи за текущий месяц?

Передайте два параметра: начало месяца и начало следующего месяца, и используйте условие Период >= &Начало И Период < &Конец. Такой вариант корректно работает со временем в датах, в отличие от МЕЖДУ с концом месяца, где легко ошибиться с границей.

Можно ли использовать функции в условиях ГДЕ?

Да, доступны функции языка запросов: НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, ГОД, МЕСЯЦ, ПОДСТРОКА, ЕСТЬNULL и другие. Например: ГДЕ НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = &День. Учтите, что функция над индексируемым полем обычно отключает использование индекса.

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

ГДЕ фильтрует строки до группировки, ИМЕЮЩИЕ — после, по агрегатным значениям. Например, отобрать товары с суммарными продажами больше тысячи: СГРУППИРОВАТЬ ПО Номенклатура ИМЕЮЩИЕ СУММА(Количество) > 1000. В ИМЕЮЩИЕ нельзя использовать поля, по которым нет группировки или агрегации.

Как отладить сложное условие с несколькими И и ИЛИ?

Разбейте условие на части и проверяйте каждую отдельно в консоли запросов, затем собирайте обратно с явными скобками. Полезно временно вывести проверяемые поля в результат запроса — так видно, какие значения реально сравниваются, и где условие отсекает нужные строки.

Итог

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

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