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

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

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

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

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

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

Материал ориентирован на встроенный язык запросов платформы «1С:Предприятие 8». Примеры применимы как в консоли запросов, так и в программном коде через объект Запрос.

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

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

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

Номенклатура.Артикул = "А-100"

Несколько условий объединяются логическими операторами И (AND), ИЛИ (OR), НЕ (NOT). Приоритет стандартный: сначала НЕ, затем И, затем ИЛИ. Скобки позволяют явно задать порядок вычисления — злоупотреблять ими не стоит, но при смешении И и ИЛИ они обязательны для читаемости и корректности:

ГДЕ

(Документ.Склад = &Склад ИЛИ Документ.Склад = &СкладРезерв)

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

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

Параметры запроса и операторы сравнения

Жёстко прописывать значения в тексте запроса — плохая практика. Для передачи значений используются параметры, обозначаемые амперсандом: &НаименованиеПараметра. В коде они заполняются методом УстановитьПараметр():

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

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

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

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

| И Товары.ПометкаУдаления = ЛОЖЬ";

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

Важное правило: тип значения параметра должен соответствовать типу поля. Сравнение ссылки с строкой или даты с числом не вызовет ошибки синтаксиса, но даст пустой или неверный результат. Если тип параметра заранее неизвестен, используйте функцию ВЫРАЗИТЬ(&Параметр КАК Справочник.Номенклатура).

Для сравнения доступны операторы =, <>, >, <, >=, <=. Булевы поля сравниваются с литералами ИСТИНА и ЛОЖЬ, перечисления — со значениями вида ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20).

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

Оператор В

Когда нужно сравнить поле с несколькими значениями, вместо цепочки ИЛИ применяется оператор В:

ГДЕ

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

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

Оператор В ИЕРАРХИИ

Для иерархических справочников часто нужно выбрать не только саму группу, но и все вложенные элементы. Это делает конструкция В ИЕРАРХИИ:

ГДЕ

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

Условие вернёт ИСТИНА для самой группы и всех её потомков на любой глубине. Альтернатива — сравнение Номенклатура.Родитель = &Группа — отберёт только непосредственных «детей», без вложенных подгрупп, что является частой логической ошибкой.

Отбор по шаблону: оператор ПОДОБНО

Оператор ПОДОБНО (LIKE) ищет строки по шаблону. Символ % заменяет любую последовательность символов, _ — ровно один символ, квадратные скобки [...] задают допустимый набор символов:

ГДЕ

Контрагенты.Наименование ПОДОБНО "%Ромашка%"

Такое условие найдёт «ООО Ромашка», «Ромашка-Сервис» и т.п. Если в искомом тексте встречаются служебные символы (% или _), их экранируют с помощью ключевого слова СПЕЦСИМВОЛ:

ГДЕ

Товары.Наименование ПОДОБНО "%~%" СПЕЦСИМВОЛ "~"

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

Работа с NULL и пустыми значениями

Значение NULL возникает при левых соединениях, когда в присоединённой таблице нет подходящей строки. Сравнение = NULL никогда не вернёт ИСТИНА — для проверки используется специальный оператор:

ГДЕ

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

Обратная проверка — НЕ ... ЕСТЬ NULL или ЕСТЬ НЕ NULL в зависимости от версии платформы. Чтобы заменить NULL на конкретное значение, применяется функция ЕСТЬNULL(Поле, 0) — её можно использовать и в условии, но лучше обрабатывать значение в списке выборки.

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

Типичные ошибки
01
Сравнение Поле = NULL — условие всегда ложно, нужно Поле ЕСТЬ NULL
02
Сравнение с пустой строкой вместо пустой ссылки и наоборот — результат пустой
03
Использование Родитель = &Группа вместо В ИЕРАРХИИ — теряются вложенные подгруппы
04
Передача параметра не того типа — запрос возвращает пустой результат без ошибки
05
Условие по виртуальной таблице регистра в ГДЕ вместо параметров таблицы — резкое падение производительности

Отбор в виртуальных таблицах регистров

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

ВЫБРАТЬ

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

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

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад) КАК Остатки

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

В секции ГДЕ для виртуальных таблиц остаются условия, которые нельзя выразить параметрами: например, отбор по значению остатка (Остатки.КоличествоОстаток > 0) или по реквизитам измерений.

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

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

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

Секция ГДЕ

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

Отбор в СКД

Когда запрос используется в отчёте на компоновке данных — пользователь сам управляет отборами без изменения текста запроса.

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

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

Полезный приём — временно вывести само условие в список выборки как булево выражение. Так видно, для каких строк оно истинно, и легче найти причину «пропавших» записей:

ВЫБРАТЬ

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

ВЫБОР

КОГДА Товары.Артикул = &Артикул

ТОГДА ИСТИНА

ИНАЧЕ ЛОЖЬ

КОНЕЦ КАК ПроходитОтбор

ИЗ

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

Также проверяйте типы параметров в отладчике: точка останова после УстановитьПараметр покажет фактическое значение и его тип. Неопределённое значение параметра (когда параметр не установлен) приведёт к ошибке выполнения запроса — это сразу видно при отладке.

Порядок действий при отладке условия
  1. 1
    Выполните запрос в консоли без секции ГДЕ и оцените исходные данные
  2. 2
    Добавьте условия по одному, контролируя число строк после каждого
  3. 3
    Проверьте типы и значения параметров в отладчике
  4. 4
    Для виртуальных таблиц перенесите отбор по измерениям в параметры таблицы
  5. 5
    Сравните время выполнения до и после оптимизации на реальном объёме данных

Частые ошибки и их последствия

Самая коварная ошибка — логическая: запрос выполняется без сообщений об ошибках, но возвращает не те данные. Например, забытые скобки при смешении И и ИЛИ меняют смысл условия: А ИЛИ Б И В читается как А ИЛИ (Б И В), а не как (А ИЛИ Б) И В.

Вторая группа ошибок — производительность. Разыменование через точку по составному полю в условии (Документ.Контрагент.ИНН = &ИНН) порождает неявные соединения со всеми таблицами составного типа. Надёжнее соединиться с нужной таблицей явно или отобрать сначала по ссылке.

Третья группа — устаревшие данные в параметрах. Если параметр заполнен один раз, а запрос выполняется в цикле с разными условиями, легко забыть обновить значение — и все итерации вернут одинаковый результат. Устанавливайте параметры непосредственно перед каждым вызовом Выполнить().

Итог

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

Секция ГДЕ фильтрует строки запроса через логические условия с параметрами (&Имя). Используйте В ИЕРАРХИИ для групп, ПОДОБНО для поиска по шаблону, ЕСТЬ NULL для проверки отсутствующих данных. Для виртуальных таблиц регистров отбор по измерениям и периоду задавайте в параметрах таблицы. Отлаживайте условия по одному и контролируйте типы параметров.

Частые вопросы об условии ГДЕ

Можно ли использовать в ГДЕ поля табличной части документа?

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

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

Типовой приём — условие вида ГДЕ (&ОтборПоСкладу = ЛОЖЬ ИЛИ Склад = &Склад), где первый параметр-флаг включает или отключает фильтр. Другой вариант — передавать пустое значение и проверять (&Склад = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка) ИЛИ Склад = &Склад). В отчётах на СКД необязательные отборы реализуются штатно, без таких конструкций.

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

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

Почему запрос с ГДЕ возвращает пустой результат без ошибки?

Чаще всего причина в несовпадении типов: параметр содержит строку, а поле — ссылку, или наоборот. Также проверьте лишние пробелы в строковых значениях, регистр при сравнении через ПОДОБНО и случаи, когда поле содержит NULL — такие строки не пройдут обычное сравнение.

Можно ли в ГДЕ использовать функции вроде ДАТАВРЕМЯ или НАЧАЛОПЕРИОДА?

Да, встроенные функции языка запросов допустимы в условиях: НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = &ДатаДня или сравнение с ДАТАВРЕМЯ(2026, 1, 1). Учтите, что функция над полем в левой части условия мешает использованию индекса — на больших таблицах лучше сравнивать поле с диапазоном через МЕЖДУ.

Как отобрать документы только за указанный период?

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