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