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