Как задавать условия отбора в запросах 1С 8.3

· 9 мин

Содержание

Условие отбора в запросе 1С пишут в секции ГДЕ, в условии соединения после ПО и в параметрах виртуальных таблиц. Синтаксис один и тот же: слева поле, в середине оператор сравнения, справа значение или параметр. Операторы — =, <>, >, <, >=, <=, а также МЕЖДУ, В, ПОДОБНО, ЕСТЬ NULL и ССЫЛКА.

Разберём каждый оператор с примерами, порядок вычисления логических связок И, ИЛИ, НЕ, отбор по строкам через ПОДОБНО, условия по датам и периодам, проверку на NULL и пустую ссылку. В конце — ошибки, из-за которых запрос либо возвращает не то, либо работает медленно.

Где именно в запросе ставится условие

У условия в запросе четыре места, и выбор места меняет и результат, и скорость:

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

Простой пример отбора по складу и организации:

ВЫБРАТЬ
    Товары.Номенклатура,
    Товары.Количество
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
    Товары.Ссылка.Организация = &Организация
    И Товары.Ссылка.Склад = &Склад

Значения почти всегда передавайте через параметры (&Организация), а не литералами в тексте. Это защищает от ошибок типов и позволяет платформе кэшировать план запроса.

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

-- оставит ВСЕ товары, скидку подтянет только у акционных
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Скидки КАК Ск
    ПО Ск.Номенклатура = Товары.Номенклатура И Ск.Акция = ИСТИНА

-- оставит ТОЛЬКО акционные товары — левое соединение превратилось в полное
... ГДЕ Ск.Акция = ИСТИНА

Если по теме отчёта нужны все товары — условие на правую таблицу ставят в ПО, а не в ГДЕ.

Операторы сравнения: равно, больше, диапазон, список

Базовый набор знаком по математике, но есть нюансы написания.

ОператорЧто проверяетПример
=равенствоЦена = 0
<>не равно (не !=)Статус <> &Закрыт
> < >= <=сравнение величин и датКоличество >= 10
МЕЖДУ … И …попадание в диапазон, границы включаютсяСумма МЕЖДУ 1000 И 5000
В (…)значение входит в списокВид В (&Вид1, &Вид2)
В ИЕРАРХИИ (…)элемент и все его подчинённыеГруппа В ИЕРАРХИИ (&ПапкаТоваров)
ССЫЛКАпроверка типа ссылочного поляРегистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг

Неравенство пишется ровно <>. Запись != язык запросов не понимает и выдаёт синтаксическую ошибку — это частый перенос привычки из других языков.

В принимает не только перечисление параметров, но и вложенный запрос:

ГДЕ
    Товары.Номенклатура В
        (ВЫБРАТЬ Отбор.Номенклатура ИЗ РегистрСведений.СписокАкций КАК Отбор)

В ИЕРАРХИИ работает только со ссылочными полями, у которых есть иерархия (группы справочника, иерархия счетов). Для плоского справочника он бессмыслен.

Логические связки И, ИЛИ, НЕ и порядок их вычисления

Несколько условий соединяют тремя операторами: И, ИЛИ, НЕ. Порядок вычисления фиксированный:

  1. Сначала НЕ.
  2. Потом И.
  3. В последнюю очередь ИЛИ.

Из-за этого запись без скобок часто отбирает не то, что задумано. Сравните:

ГДЕ Организация = &Орг И Сумма > 1000 ИЛИ Проведён = ЛОЖЬ

Платформа прочитает это как (Организация = &Орг И Сумма > 1000) ИЛИ (Проведён = ЛОЖЬ) — и вернёт заодно все непроведённые документы любой организации. Если нужно было ограничить одной организацией, ставьте скобки:

ГДЕ Организация = &Орг И (Сумма > 1000 ИЛИ Проведён = ЛОЖЬ)

Когда в условии есть и И, и ИЛИ, расставляйте скобки всегда, даже если по приоритету они не обязательны. Явные скобки читаются однозначно и спасают при доработке запроса через полгода.

Оператор НЕ удобен для инверсии ПОДОБНО и В:

ГДЕ НЕ Номенклатура.Наименование ПОДОБНО "%образец%"
Проверьте себя
Как платформа вычислит условие `А = 1 ИЛИ Б = 2 И В = 3` без скобок?
Что вернёт `Сумма МЕЖДУ 1000 И 5000`, если сумма ровно 5000?

Отбор по тексту: оператор ПОДОБНО и спецсимволы

Для поиска по части строки используют ПОДОБНО (аналог LIKE в SQL). Шаблон собирают из обычных символов и подстановочных знаков:

  • % — любое количество любых символов, в том числе ноль.
  • _ — ровно один любой символ.
  • [аеёиоуыэюя] — один символ из перечисленного набора.
  • [а-я] — один символ из диапазона.
  • [^0-9] — один символ, которого нет в наборе.

Примеры:

-- наименование начинается на «Болт»
ГДЕ Номенклатура.Наименование ПОДОБНО "Болт%"

-- артикул из пяти символов, первый «А»
ГДЕ Товар.Артикул ПОДОБНО "А____"

-- где-то внутри встречается «кабель»
ГДЕ Номенклатура.Наименование ПОДОБНО "%кабель%"

Если сам символ %, _ или [ должен искаться буквально, экранируйте его и объявите экранирующий знак через СПЕЦСИМВОЛ:

ГДЕ Комментарий ПОДОБНО "%30~%скидка%" СПЕЦСИМВОЛ "~"

Здесь ~% означает буквальный процент, а остальные % работают как подстановка.

ПОДОБНО в 1С не зависит от регистра для строк — «Болт» и «БОЛТ» найдутся одинаково. На поведение влияет настройка сравнения строк в информационной базе, но для типовых баз регистр не важен.

Главный минус ПОДОБНО — про скорость. Шаблон, который начинается с % или _, не может использовать индекс: платформа перебирает всю таблицу. Поэтому "Болт%" быстрый, а "%болт%" на больших справочниках медленный.

Условия по датам и периодам

Дата в запросе — это момент с точностью до секунды. Поэтому отбор «за сегодня» через = &Дата почти никогда не срабатывает: у документов разное время.

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

ВЫБРАТЬ
    Док.Ссылка
ИЗ
    Документ.РеализацияТоваровУслуг КАК Док
ГДЕ
    Док.Дата МЕЖДУ &НачалоПериода И &КонецПериода

Полезные функции для работы с датами прямо в запросе:

  • НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) — начало дня, месяца, квартала, года.
  • КОНЕЦПЕРИОДА(Дата, МЕСЯЦ) — конец периода (с временем 23:59:59).
  • ДОБАВИТЬКДАТЕ(Дата, ДЕНЬ, -7) — сдвиг на интервал.
  • ДАТАВРЕМЯ(2026, 1, 1) — литерал даты прямо в тексте запроса.
  • РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ) — число периодов между датами.

Отбор «с начала месяца по текущую дату» целиком внутри запроса:

ГДЕ Док.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Текущая, МЕСЯЦ) И &Текущая

Если задать КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), в выборку попадут документы вплоть до 23:59:59. А вот МЕЖДУ НачалоДня И НачалоСледующегоДня захватит лишнюю полночь — используйте именно КОНЕЦПЕРИОДА.

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

ИЗ РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Обороты

Пустые значения: NULL и пустая ссылка — это разное

Две частые причины, по которым запрос «теряет» строки, — путаница между NULL и пустой ссылкой.

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

ГДЕ Остатки.КоличествоОстаток ЕСТЬ NULL      -- значения нет
ГДЕ Остатки.КоличествоОстаток ЕСТЬ НЕ NULL   -- значение есть

Чтобы подставить вместо NULL число или пустую строку, применяют функцию ЕСТЬNULL:

ВЫБРАТЬ ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

Пустая ссылка — это заполненное значение ссылочного типа, просто «пустышка» (незаполненный реквизит Контрагент, например). Она не равна NULL. Проверяют её через ЗНАЧЕНИЕ:

ГДЕ Док.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)

Для перечислений и предопределённых элементов тот же оператор ЗНАЧЕНИЕ даёт конкретное значение без параметра:

ГДЕ Док.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа)

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

Условие внутри поля: конструкция ВЫБОР КОГДА

Иногда условие нужно не для отбора строк, а чтобы вычислить значение колонки. Для этого есть ВЫБОР (аналог CASE):

ВЫБРАТЬ
    Док.Ссылка,
    ВЫБОР
        КОГДА Док.Сумма > 100000 ТОГДА "Крупный"
        КОГДА Док.Сумма > 10000  ТОГДА "Средний"
        ИНАЧЕ "Мелкий"
    КОНЕЦ КАК КатегорияСуммы

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

СУММА(ВЫБОР КОГДА Док.Проведён ТОГДА Док.Сумма ИНАЧЕ 0 КОНЕЦ)

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

Типичные ошибки и ускорение отбора

Ошибки, которые встречаются чаще всего:

  1. Сравнение с NULL через =. Пишут Поле = NULL и удивляются пустому результату. Только ЕСТЬ NULL.
  2. Нет скобок при смеси И и ИЛИ. Запрос возвращает лишние строки из-за приоритета И над ИЛИ.
  3. Отбор по дате через =. Документ с временем 14:30 не найдётся по = НачалоДня. Нужен диапазон МЕЖДУ.
  4. Условие в ГДЕ вместо параметров виртуальной таблицы. Остатки читаются целиком, потом фильтруются — медленно на больших регистрах.
  5. ПОДОБНО "%текст%" по большому справочнику. Ведущий % отключает индекс.

Приёмы, которые ускоряют отбор:

  • ✅ Ставьте условие как можно раньше — в параметры виртуальной таблицы, а не в итоговое ГДЕ.
  • ✅ Сравнивайте индексированные поля (измерения регистров, ссылки). Отбор по неиндексированному реквизиту тянет полное сканирование.
  • ✅ Не оборачивайте поле в функцию в условии: ГОД(Дата) = 2026 мешает индексу, а Дата МЕЖДУ НачалоГода И КонецГода — нет.
  • ✅ ИЛИ по разным полям часто мешает оптимизатору; иногда быстрее объединить два запроса через ОБЪЕДИНИТЬ.
  • ✅ Проверяйте план и время на боевом объёме данных, а не на пустой демо-базе.

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

Чем `<>` отличается от `!=` в запросе 1С?
Неравенство в языке запросов пишется только <>. Символ != не поддерживается и вызывает синтаксическую ошибку при проверке запроса.
Почему условие по дате ничего не находит?
Скорее всего, сравнение идёт через = с датой без времени, а у документов время заполнено. Используйте диапазон Дата МЕЖДУ НачалоПериода И КонецПериода и функцию КОНЕЦПЕРИОДА для верхней границы.
Как в условии проверить, что реквизит не заполнен?
Если это ссылочный реквизит — сравните с пустой ссылкой: Поле <> ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка). Если значение пришло из соединения и может отсутствовать — проверяйте Поле ЕСТЬ NULL.
Можно ли в условии `В` подставить список из другого запроса?
Да. После В ставят либо перечисление значений в скобках, либо вложенный запрос, возвращающий одну колонку. Для иерархических справочников удобнее В ИЕРАРХИИ.
Почему поиск `ПОДОБНО "%слово%"` работает медленно?
Шаблон с % в начале не может использовать индекс, и платформа перебирает всю таблицу. По возможности стройте шаблон от начала строки ("слово%") или ограничивайте выборку другими условиями.