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

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

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

Как задать условие ГДЕ в конструкторе запроса 1С: закладка «Условия», параметры, виртуальные таблицы, типичные ошибки и проверка результата запроса.

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

Материал рассчитан на разработчиков и внедренцев, которые работают в конфигураторе 1С:Предприятие 8.3. Разберём, где в конструкторе задаётся ГДЕ, как формируются простые и составные условия, когда отбор нужно переносить в параметры виртуальной таблицы и как проверить, что запрос возвращает именно те данные, которые ожидались.

Где в конструкторе запроса находится условие ГДЕ

Конструктор запроса открывается из модуля: при наборе текста запроса правой кнопкой выбирается пункт «Конструктор запроса», либо конструктор вызывается автоматически при создании объекта Запрос через волшебную строку. Все настройки распределены по закладкам, и условие ГДЕ собирается на закладке «Условия».

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

Несколько условий по умолчанию объединяются логическим И. Если нужна логика ИЛИ или группировка скобками, используются кнопки группировки на панели закладки: условия выделяются и объединяются в группу «Или» либо «И». Для отрицания целой группы применяется группа «Не».

Простые условия: равенство, сравнение, параметры

Самый частый сценарий — отбор по равенству: ГДЕ Склад = &Склад. В конструкторе поле «Склад» перетаскивается в условия, выбирается вид сравнения «=», а в поле значения вписывается &Склад. Перед выполнением запроса параметр устанавливается в коде: Запрос.УстановитьПараметр("Склад", СкладСсылка). Если параметр не установить, запрос завершится с ошибкой — это одна из самых частых причин «пустых» падений у начинающих.

Для числовых и дата-сравнений используются операторы >, <, >=, <=. С датами важно помнить: дата без времени в 1С означает начало дня, поэтому условие Дата <= &КонецПериода с параметром «31.01» не включит документы, проведённые в течение 31 января. Корректные варианты — передать конец дня через КонецДня() в коде либо использовать Дата < &СледующийДень.

Константные значения тоже допустимы: ГДЕ ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар). Конструктор позволяет выбрать такое значение из списка, если тип поля известен. Константы уместны, когда условие действительно фиксировано логикой отчёта; во всех остальных случаях лучше параметр — он не требует переписывания текста запроса при изменении отбора.

Составные условия: И, ИЛИ, НЕ и скобки

Реальные отборы редко ограничиваются одним условием. Типичный пример: документы по организации И по складу И за период. В конструкторе три условия просто добавляются подряд — они автоматически соединяются через И, и запрос вернёт только строки, удовлетворяющие всем требованиям одновременно.

Когда нужна альтернатива — например, товары из группы «А» или группы «Б» — условия выделяются и группируются кнопкой «Сгруппировать условия (ИЛИ)». В тексте запроса появится конструкция ГДЕ (Номенклатура.Родитель = &ГруппаА ИЛИ Номенклатура.Родитель = &ГруппаБ). Скобки здесь критичны: без них приоритет И выше ИЛИ, и логика отбора исказится.

Отдельного внимания заслуживает оператор НЕ. Группа «Не» инвертирует условие целиком: НЕ (Количество > 0). Однако для простых случаев читабельнее обратное сравнение (Количество <= 0), а для проверки на NULL вместо НЕ (Поле ЕСТЬ NULL) понятнее Поле НЕ ЕСТЬ NULL. Чем проще текст условия, тем легче его отладить коллеге через полгода.

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

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

Оператор В проверяет вхождение значения в список: ГДЕ Склад В (&СписокСкладов). В конструкторе для этого выбирается вид сравнения «В списке», а параметром передаётся массив или список значений. Это стандартный способ отбора по нескольким элементам без длинной цепочки ИЛИ.

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

Оператор ПОДОБНО работает со строками по шаблону: Наименование ПОДОБНО "%кабель%", где % — любое количество символов, _ — ровно один символ. Учитывайте, что поиск по ПОДОБНО с маской в начале строки не использует индекс и на больших таблицах работает медленно. Проверка ЕСТЬ NULL обязательна там, где поле может остаться незаполненным после левого соединения таблиц — сравнение с NULL через «=» никогда не вернёт истину.

ГДЕ или параметры виртуальной таблицы: в чём разница

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

Параметры виртуальной таблицы задаются в конструкторе на закладке «Таблицы»: выделяется виртуальная таблица, нажимается кнопка «Параметры виртуальной таблицы», и в открывшемся диалоге заполняется поле «Условие» — например, Склад = &Склад. Такой отбор применяется на уровне построения виртуальной таблицы: СУБД сразу выбирает только нужные строки из регистра, и дальнейшие соединения работают с уже сокращённым набором данных.

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

Сравнение вариантов отбора

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

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

Условие ГДЕ основного запроса

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

Отбор в СКД вместо текста запроса

Подходит, когда пользователь сам настраивает отборы в отчёте; условие в тексте запроса тогда лучше не дублировать

Проверка результата и отладка условия

После сборки условия запрос нужно проверить на реальных данных. Базовый способ — временно выполнить запрос в отладчике: установить точку останова после Запрос.Выполнить(), вычислить выражение Результат.Выгрузить() и просмотреть таблицу значений. Сразу видно, сколько строк вернулось и попали ли в выборку ожидаемые документы.

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

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

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

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

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

Совпадает с ожиданием по контрольному примеру (например, числу документов за день)

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

Ноль строк или заметно больше ожидаемого — проверяйте условия по одному

Типы параметров
Норма

Параметр содержит ссылку нужного типа или дату с корректным временем

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

Строка вместо ссылки, дата без времени для конца периода

Попадание граничных данных
Норма

Документы первого и последнего дня периода присутствуют

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

Выпадает последний день — ошибка в границе даты

Типичные ошибки и ограничения

Первая группа ошибок — логические: перепутанные И/ИЛИ без скобок, Родитель = вместо В ИЕРАРХИИ, отбор по строковому представлению ссылки вместо самой ссылки. Такие ошибки не вызывают падения запроса — он честно выполняется и возвращает неправильные данные, что опаснее любой ошибки выполнения.

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

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

Порядок настройки условия ГДЕ
  1. 1
    Откройте конструктор запроса и выберите нужные таблицы на закладке «Таблицы и поля»
  2. 2
    Если используется виртуальная таблица регистра — задайте отбор в её параметрах через кнопку «Параметры виртуальной таблицы»
  3. 3
    Перейдите на закладку «Условия» и перетащите нужные поля из списка доступных
  4. 4
    Для каждого условия выберите вид сравнения и укажите параметр (&Имя) или константу
  5. 5
    Сгруппируйте условия через И/ИЛИ при необходимости, проверьте расстановку скобок в тексте запроса
  6. 6
    Установите все параметры в коде и выполните запрос на тестовых данных
  7. 7
    Сравните результат с контрольным примером и при расхождении проверяйте условия по одному
Итог

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

Условие ГДЕ настраивается на закладке «Условия» конструктора запроса: поле, оператор, параметр или константа. Отбор по измерениям виртуальных таблиц регистров выносите в параметры таблицы — это главный фактор скорости. Проверяйте границы дат, типы параметров и логику И/ИЛИ на контрольных примерах до переноса запроса в рабочий код.

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

Чем закладка «Условия» отличается от закладки «Связи» в конструкторе?

Закладка «Связи» описывает, как соединяются таблицы между собой (левое, внутреннее соединение и по каким полям) — это конструкция СОЕДИНЕНИЕ. Закладка «Условия» формирует секцию ГДЕ, которая фильтрует уже полученный результат. Отбор по полю одной таблицы обычно делается в ГДЕ, а не в условии связи.

Можно ли в условии ГДЕ использовать подзапрос?

Да, например: ГДЕ Номенклатура В (ВЫБРАТЬ Товар ИЗ ...). Конструктор частично поддерживает такие конструкции, но сложные подзапросы удобнее дописывать вручную в тексте запроса после сборки основного каркаса.

Почему условие по дате не отбирает документы последнего дня периода?

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

Как отобрать записи, где поле не заполнено?

Используйте Поле ЕСТЬ NULL для проверки на NULL (актуально после левых соединений) или сравнение с пустой ссылкой: Поле = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка). Сравнение Поле = NULL не работает — оно всегда ложно.

Когда отбор лучше делать не в запросе, а в настройках СКД?

Когда отчёт строится на СКД и пользователь должен сам управлять отборами в форме отчёта. В этом случае в тексте запроса оставляют только жёсткие служебные условия, а пользовательские отборы добавляют на закладке «Отбор» настроек СКД — иначе условия задублируются и будут конфликтовать.

Конструктор не открывает мой запрос — что делать?

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