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