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

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

Как задать условие в запросе 1С

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

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

Основной инструмент отбора — секция ГДЕ (в английском синтаксисе — WHERE). В ней описываются логические выражения: сравнения полей с параметрами, проверки вхождения в список, диапазоны дат, шаблоны строк. Условия можно комбинировать операторами И, ИЛИ, НЕ и группировать скобками.

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

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

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

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

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

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Ссылка КАК Товар,

| Товары.Наименование

|ИЗ

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

|ГДЕ

| Товары.Родитель = &Группа";

Запрос.УстановитьПараметр("Группа", ГруппаТоваров);

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

Доступные операторы сравнения: = (равно), <> (не равно), >, <, >=, <=. Сравнивать можно поля с параметрами, поля между собой и поля с литералами (константами, записанными прямо в тексте запроса). Литералы строк пишутся в кавычках, даты — через функцию ДАТАВРЕМЯ(2026, 1, 1), ссылочные значения лучше передавать параметром.

Несколько условий объединяются операторами И (должны выполняться оба) и ИЛИ (достаточно одного). Оператор И имеет более высокий приоритет, чем ИЛИ, поэтому при смешанных условиях используйте скобки, иначе логика отбора будет отличаться от задуманной.

ГДЕ

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

| ИЛИ Документ.Организация = &Организация2)

| И Документ.Проведен

Специальные операторы условий: В, МЕЖДУ, ПОДОБНО, ЕСТЬ NULL

Помимо простых сравнений, язык запросов 1С предоставляет специальные операторы для типовых задач отбора. Они делают текст запроса короче и читаемее, чем цепочки условий через ИЛИ.

Оператор В — проверка вхождения в список

Оператор В проверяет, входит ли значение поля в заданный список или результат вложенного запроса. Список можно перечислить в скобках или передать параметром-массивом (параметром-списком значений).

ГДЕ

| Товары.ВидНоменклатуры В (&Вид1, &Вид2)

| И Товары.Ссылка В (&СписокТоваров)

Для передачи массива параметром достаточно вызвать УстановитьПараметр("СписокТоваров", МассивСсылок) — платформа сама развернёт массив в список значений. Оператор НЕ В выполняет обратную проверку.

Оператор В ИЕРАРХИИ — отбор по группе с подгруппами

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

ГДЕ

| Товары.Ссылка В ИЕРАРХИИ (&Группа)

Операторы МЕЖДУ, ПОДОБНО и ЕСТЬ NULL

МЕЖДУ ... И ... проверяет попадание значения в диапазон включительно — удобно для дат и чисел. ПОДОБНО ищет строки по шаблону: символ % заменяет любую последовательность символов, _ — один символ. ЕСТЬ NULL / НЕ ЕСТЬ NULL проверяют незаполненность значения, что особенно актуально после левых соединений таблиц.

ГДЕ

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

| И Контрагент.Наименование ПОДОБНО &Маска

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

Условия в параметрах виртуальных таблиц

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

ВЫБРАТЬ

| Остатки.Номенклатура,

| Остатки.КоличествоОстаток

|ИЗ

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

| &ДатаОстатков,

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

| И Номенклатура В ИЕРАРХИИ (&Группа)) КАК Остатки

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

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

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

Условие в параметрах виртуальной таблицы

Отбор применяется до вычисления итогов. Быстро, но работает только по измерениям регистра.

Условие в секции ГДЕ

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

Условие в соединении (ПО)

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

Условия в соединениях и в секции ИМЕЮЩИЕ

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

ВЫБРАТЬ

| Товары.Ссылка,

| Цены.Цена

|ИЗ

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

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, ) КАК Цены

| ПО Товары.Ссылка = Цены.Номенклатура

| И Цены.ТипЦен = &ТипЦен

После группировки (СГРУППИРОВАТЬ ПО) обычная секция ГДЕ уже неприменима к агрегатным значениям — для отбора сгруппированных строк используется секция ИМЕЮЩИЕ (HAVING). Например, отобрать только контрагентов, у которых сумма продаж превышает порог:

СГРУППИРОВАТЬ ПО

| Продажи.Контрагент

|ИМЕЮЩИЕ

| СУММА(Продажи.СуммаОборот) > &МинимальнаяСумма

Типичные ошибки
01
Условие по измерению регистра вынесено в ГДЕ вместо параметров виртуальной таблицы — запрос вычисляет лишние итоги и работает в разы медленнее.
02
Условие по правой таблице записано в ГДЕ при левом соединении — строки без совпадений теряются, итоги занижены.
03
Сравнение с пустой ссылкой через параметр, который не заполнен, — параметр имеет значение Неопределено, и запрос падает с ошибкой.
04
Смешение И и ИЛИ без скобок — из-за приоритета операторов отбор срабатывает не так, как задумано.

Передача параметров из кода и проверка результата

На стороне встроенного языка работа с условиями сводится к трём шагам: написать текст запроса, установить все параметры, выполнить и проверить результат. Пропуск любого параметра — самая частая причина ошибки «Ошибка при выполнении запроса» с указанием номера строки.

Порядок действий
  1. 1
    Сформулируйте условие в секции ГДЕ или в параметрах виртуальной таблицы, используя именованные параметры с амперсандом.
  2. 2
    Вызовите Запрос.УстановитьПараметр для каждого параметра до выполнения запроса; для списков передавайте массив или список значений.
  3. 3
    Выполните запрос и проверьте РезультатЗапроса.Пустой(), прежде чем обходить выборку.
  4. 4
    Проверьте на тестовых данных граничные случаи: пустой отбор, отбор по группе, период без документов.
  5. 5
    Для медленных запросов откройте консоль запросов и сравните план с условием в ГДЕ и в параметрах виртуальной таблицы.

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

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

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

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

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

Совпадает с ожидаемым по тестовым данным

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

Строк меньше — условие слишком строгое; больше — проверьте И/ИЛИ и скобки

Значения параметров в консоли запросов
Норма

Все параметры заполнены нужными типами

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

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

Время выполнения на рабочей базе
Норма

Сопоставимо с аналогичными запросами

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

Запрос «зависает» — условие по измерению не в параметрах виртуальной таблицы

Частые вопросы об условиях в запросах 1С

Как задать условие «не равно» в запросе 1С?

Используйте оператор <>, например: ГДЕ Документ.ПометкаУдаления = ЛОЖЬ И Документ.Статус <> &СтатусОтменен. Для списков исключений применяйте НЕ В: ГДЕ НЕ Товар.ВидНоменклатуры В (&ИсключаемыеВиды).

Как отобрать записи за период?

Через оператор МЕЖДУ: ГДЕ Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода. Границы включаются в диапазон. Учтите, что у даты есть время: если конец периода задан как начало дня, документы позже 00:00:00 этого дня не попадут в выборку — задавайте конец дня (КонецДня(Дата)) или используйте строгое неравенство с датой следующего дня.

Можно ли использовать функции встроенного языка в условии запроса?

Нет. В тексте запроса доступны только функции языка запросов: ДАТАВРЕМЯ, РАЗНОСТЬДАТ, НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, ПОДСТРОКА, ВЫРАЗИТЬ и другие. Функции вроде СокрЛП или Формат из встроенного языка в запросе не работают — вычислите значение заранее и передайте его параметром.

Как задать условие по реквизиту реквизита (через точку)?

Через разыменование: ГДЕ Документ.Контрагент.ИНН = &ИНН. Работает, но каждое обращение через точку к ссылочному полю — это неявное соединение с таблицей справочника, что утяжеляет запрос. Если реквизитов много, лучше явно соединить таблицу контрагентов и забрать поля из неё.

Почему условие с ПОДОБНО не находит строки, хотя подстрока есть?

Проверьте регистр символов — ПОДОБНО регистрозависим в большинстве случаев, а также наличие пробелов и неразрывных пробелов в данных. Убедитесь, что спецсимволы % и _ в искомой строке экранированы через конструкцию СПЕЦСИМВОЛ, если они должны искаться как обычные знаки.

Чем отличается ГДЕ от ИМЕЮЩИЕ?

ГДЕ фильтрует строки до группировки и не может ссылаться на агрегатные функции. ИМЕЮЩИЕ применяется после группировки и работает с результатами СУММА, КОЛИЧЕСТВО, МАКСИМУМ и других агрегатов. Если нужно отобрать группы по итоговому значению — только ИМЕЮЩИЕ.

Итог

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

Условия задаются в секции ГДЕ через сравнения и операторы В, В ИЕРАРХИИ, МЕЖДУ, ПОДОБНО, ЕСТЬ NULL. Для виртуальных таблиц отбор по измерениям переносите в их параметры — это главный резерв производительности. При левом соединении следите, где записано условие: в ПО или в ГДЕ. Все параметры устанавливайте до выполнения запроса и проверяйте результат на пустоту.