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

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

Условие ГДЕ в запросе 1С: как правильно отбирать данные

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

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

Синтаксис секции прост: после слова ГДЕ перечисляются логические выражения, объединённые операторами И, ИЛИ и НЕ. Однако на практике начинающие разработчики сталкиваются с нюансами: сравнением с NULL, отбором по иерархии справочника, поиском по части строки и передачей параметров из кода. Каждая из этих задач решается своим приёмом.

Материал разбирает конструкцию ГДЕ от базового сравнения до сложных составных условий, показывает типовые ошибки и способы проверить, что запрос отбирает именно те данные, которые нужны.

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

Минимальный запрос с отбором выглядит так: указываются поля, источник данных и условие после ключевого слова ГДЕ. Условие — это логическое выражение, которое для каждой строки таблицы вычисляется как истина или ложь; в результат попадают только строки со значением «истина».

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

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

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

Если условие ссылается на поле, по которому в таблице есть индекс (например, ссылка, дата документа, код), запрос выполняется быстро. Отбор по неиндексированным полям на большой таблице приводит к полному перебору записей и заметным паузам.

Операторы сравнения и логические связки

В условиях доступны стандартные операторы: равно (=), не равно (<> или !=), больше, меньше, больше или равно, меньше или равно. Они применимы к числам, датам, строкам и ссылкам. Для ссылок осмысленны в основном равенство и неравенство.

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

ГДЕ

(Документ.Организация = &Организация

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

ИЛИ Документ.СуммаДокумента > 1000000

Оператор МЕЖДУ включает границы диапазона: условие «Дата МЕЖДУ &Начало И &Конец» вернёт и документы ровно на граничные даты. Это удобно для периодов, но

Работа с параметрами запроса

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

Параметры устанавливаются методом УстановитьПараметр объекта Запрос до вызова Выполнить. Имя параметра указывается без амперсанда:

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

Запрос.Текст = "ВЫБРАТЬ.. ГДЕ Номенклатура = &Номенклатура";

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

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

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

Типичные ошибки
01
Подстановка значений конкатенацией строк вместо параметров — запрос ломается на датах и строках с кавычками
02
Параметр объявлен в тексте запроса, но не установлен через УстановитьПараметр — ошибка при выполнении
03
Отсутствие скобок при смешении И и ИЛИ — условие работает не так, как задумано
04
Сравнение поля со значением NULL через знак равенства — строки с NULL молча выпадают из результата

Специальные операторы: В, В ИЕРАРХИИ, ПОДОБНО

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

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

ГДЕ

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

В качестве параметра передаётся массив или список значений. Это заменяет длинную цепочку условий через ИЛИ и работает быстрее. Обратный отбор — НЕ В — исключает перечисленные значения.

Отбор по группе справочника — В ИЕРАРХИИ

Для иерархических справочников (номенклатура, контрагенты, статьи затрат) отбор по группе со всеми вложенными подгруппами делается оператором В ИЕРАРХИИ. Обычное равенство вернёт только элементы, лежащие непосредственно в указанной группе, а В ИЕРАРХИИ — всё поддерево:

ГДЕ

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

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

Поиск по части строки — ПОДОБНО

Оператор ПОДОБНО ищет строковое совпадение по шаблону. Символ «%» заменяет любую последовательность символов, «_» — ровно один символ. Пример поиска по фрагменту наименования:

ГДЕ

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

В коде параметр обычно формируют как "%" + Фрагмент + "%", чтобы искать вхождение в любом месте строки. Поиск с «%» в начале шаблона не использует индекс и на больших справочниках работает медленно — для полнотекстового поиска лучше подходят штатные механизмы полнотекстового поиска платформы.

Выбор оператора отбора

= (равенство)

Точное совпадение по ссылке, числу, дате. Самый быстрый вариант при наличии индекса.

В (&Список)

Несколько допустимых значений через массив. Заменяет цепочку ИЛИ.

В ИЕРАРХИИ

Отбор по группе иерархического справочника со всеми вложенными элементами. Дороже по времени.

ПОДОБНО

Поиск по фрагменту строки. Не использует индекс при шаблоне, начинающемся с %.

Сравнение с NULL и пустыми значениями

NULL в запросах 1С возникает при левом соединении таблиц, когда в присоединяемой таблице не нашлось пары, а также в полях составного типа, где значение не заполнено. Главное правило: NULL нельзя сравнивать через равенство. Выражение «Поле = NULL» никогда не истинно, и строки молча выпадают из результата без какой-либо ошибки.

Правильная проверка — операторы ЕСТЬ NULL и НЕ ЕСТЬ NULL:

ГДЕ

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

Если NULL нужно заменить конкретным значением уже в выборке, используйте функцию ЕСТЬNULL(Поле, ЗначениеЗамены) в списке полей или прямо в условии: ГДЕ ЕСТЬNULL(Остатки.Количество, 0) > 0. Это делает запрос устойчивым к отсутствующим данным.

Отдельно различайте NULL и пустые ссылки. Пустая ссылка справочника — это не NULL, а вполне конкретное значение; отбор по ней делается через параметр со значением Справочники.ИмяСправочника.ПустаяСсылка() или через функцию ЗНАЧЕНИЕ(Справочник.ИмяСправочника.ПустаяСсылка) в тексте запроса.

Условия в виртуальных таблицах и секции ПО

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

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки(

&Период,

Склад = &Склад

И Номенклатура В (&СписокНоменклатуры)) КАК Остатки

Правило простое: всё, что можно отфильтровать параметрами виртуальной таблицы, фильтруйте там. Условие в ГДЕ оставляйте для полей, которые недоступны в параметрах, и для объединённых логических проверок.

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

Порядок построения условия
  1. 1
    Определите, какие поля участвуют в отборе, и проверьте, есть ли по ним индексы
  2. 2
    Отборы по измерениям регистра перенесите в параметры виртуальной таблицы
  3. 3
    Остальные условия запишите в ГДЕ через параметры с амперсандом
  4. 4
    Сгруппируйте скобками сочетания И и ИЛИ
  5. 5
    Проверьте поля из левых соединений на NULL и добавьте ЕСТЬ NULL или ЕСТЬNULL
  6. 6
    Установите все параметры в коде и выполните запрос на тестовых данных

Проверка результата и типичные ошибки

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

Частые причины «пустого» результата: параметр не установлен или установлен пустым значением; сравнение строк разной длины (строка фиксированной длины дополняется пробелами, и равенство не срабатывает); сравнение даты с временем против даты без времени; отбор по пометке удаления там, где её нет в данных.

Признак «лишних» строк — чаще всего нехватка условия по периоду, организации или признаку проведения документа. Для документов почти всегда нужен отбор Проведен = ИСТИНА, иначе в отчёт попадут черновики и распроведённые документы.

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

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

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

Уменьшилось в ожидаемой пропорции

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

Не изменилось или стало нулём без причины

Установка параметров в коде
Норма

Каждый параметр из текста установлен через УстановитьПараметр

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

Ошибка «Параметр не найден» при выполнении

Поля из левых соединений
Норма

Условие учитывает NULL или находится в секции ПО

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

Строки без пары пропадают из результата

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

Учтена фиксированная длина строки (подстрока СОКРЛ или приведение)

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

Равенство строк не срабатывает из-за пробелов

Ещё один рабочий приём — временно вывести в список полей само проверяемое выражение и значения полей, участвующих в условии. Так видно, какие именно данные приходят из базы и почему сравнение даёт неожиданный результат.

Итог

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

Условие ГДЕ фильтрует строки по логическим выражениям; значения передаются только параметрами; NULL проверяется через ЕСТЬ NULL; отборы по измерениям регистров выносятся в параметры виртуальных таблиц; сочетания И и ИЛИ всегда группируются скобками; результат проверяется сравнением количества строк до и после добавления условия.

Частые вопросы

Чем ГДЕ отличается от ИМЕЮЩИЕ в запросе 1С?

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

Как отобрать документы за период, включая весь последний день?

Передайте в параметр конца периода конец дня (функция КонецДня в коде) либо используйте условие «Дата < &СледующийДень», где следующий день — начало суток после последнего дня периода. Оба способа корректно захватывают документы, проведённые в любое время последнего дня.

Почему условие «Поле = &Параметр» не находит строки, хотя значение есть?

Чаще всего причины три: параметр не установлен или содержит пустое значение; сравниваются значения разных типов (например, строка и ссылка); строковое поле имеет фиксированную длину и добито пробелами. Проверьте тип и содержимое параметра в отладчике и тип поля в конфигураторе.

Можно ли использовать несколько условий В ИЕРАРХИИ в одном запросе?

Да, их можно комбинировать через И и ИЛИ, а параметром передать массив групп. Но каждая проверка иерархии увеличивает время выполнения, поэтому на больших таблицах иногда выгоднее заранее вычислить список элементов поддерева и отбирать обычным оператором В.

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

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

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

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