Как задавать условия отбора в запросах 1С 8.3
Содержание
Условие отбора в запросе 1С пишут в секции ГДЕ, в условии соединения после ПО и в параметрах виртуальных таблиц. Синтаксис один и тот же: слева поле, в середине оператор сравнения, справа значение или параметр. Операторы — =, <>, >, <, >=, <=, а также МЕЖДУ, В, ПОДОБНО, ЕСТЬ NULL и ССЫЛКА.
Разберём каждый оператор с примерами, порядок вычисления логических связок И, ИЛИ, НЕ, отбор по строкам через ПОДОБНО, условия по датам и периодам, проверку на NULL и пустую ссылку. В конце — ошибки, из-за которых запрос либо возвращает не то, либо работает медленно.
Где именно в запросе ставится условие
У условия в запросе четыре места, и выбор места меняет и результат, и скорость:
- 🔹 Секция
ГДЕ— фильтрует итоговую выборку после всех соединений и группировок источников. - 🔹 Условие соединения
ПО— отбирает, какие строки таблиц сцепляются между собой. - 🔹 Параметры виртуальной таблицы (в фигурных скобках после имени таблицы) — ограничивают данные ещё до их чтения. Это самый быстрый способ для таблиц остатков, оборотов и среза.
- 🔹 Секция
ИМЕЮЩИЕ— условие на агрегатные функции (СУММА,КОЛИЧЕСТВО) после группировки; обычное поле туда не ставят.
Простой пример отбора по складу и организации:
ВЫБРАТЬ
Товары.Номенклатура,
Товары.Количество
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка.Организация = &Организация
И Товары.Ссылка.Склад = &Склад
Значения почти всегда передавайте через параметры (&Организация), а не литералами в тексте. Это защищает от ошибок типов и позволяет платформе кэшировать план запроса.
Разница между ГДЕ и условием соединения ПО важна при левом соединении. Условие в ПО отсеивает пары строк до того, как достроится левая часть, — строки левой таблицы сохранятся, просто поля правой будут NULL. Условие же в ГДЕ применяется к готовому результату и может выкинуть эти строки совсем.
-- оставит ВСЕ товары, скидку подтянет только у акционных
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Скидки КАК Ск
ПО Ск.Номенклатура = Товары.Номенклатура И Ск.Акция = ИСТИНА
-- оставит ТОЛЬКО акционные товары — левое соединение превратилось в полное
... ГДЕ Ск.Акция = ИСТИНА
Если по теме отчёта нужны все товары — условие на правую таблицу ставят в ПО, а не в ГДЕ.
Операторы сравнения: равно, больше, диапазон, список
Базовый набор знаком по математике, но есть нюансы написания.
| Оператор | Что проверяет | Пример |
|---|---|---|
= | равенство | Цена = 0 |
<> | не равно (не !=) | Статус <> &Закрыт |
> < >= <= | сравнение величин и дат | Количество >= 10 |
МЕЖДУ … И … | попадание в диапазон, границы включаются | Сумма МЕЖДУ 1000 И 5000 |
В (…) | значение входит в список | Вид В (&Вид1, &Вид2) |
В ИЕРАРХИИ (…) | элемент и все его подчинённые | Группа В ИЕРАРХИИ (&ПапкаТоваров) |
ССЫЛКА | проверка типа ссылочного поля | Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг |
Неравенство пишется ровно <>. Запись != язык запросов не понимает и выдаёт синтаксическую ошибку — это частый перенос привычки из других языков.
В принимает не только перечисление параметров, но и вложенный запрос:
ГДЕ
Товары.Номенклатура В
(ВЫБРАТЬ Отбор.Номенклатура ИЗ РегистрСведений.СписокАкций КАК Отбор)
В ИЕРАРХИИ работает только со ссылочными полями, у которых есть иерархия (группы справочника, иерархия счетов). Для плоского справочника он бессмыслен.
Логические связки И, ИЛИ, НЕ и порядок их вычисления
Несколько условий соединяют тремя операторами: И, ИЛИ, НЕ. Порядок вычисления фиксированный:
- Сначала
НЕ. - Потом
И. - В последнюю очередь
ИЛИ.
Из-за этого запись без скобок часто отбирает не то, что задумано. Сравните:
ГДЕ Организация = &Орг И Сумма > 1000 ИЛИ Проведён = ЛОЖЬ
Платформа прочитает это как (Организация = &Орг И Сумма > 1000) ИЛИ (Проведён = ЛОЖЬ) — и вернёт заодно все непроведённые документы любой организации. Если нужно было ограничить одной организацией, ставьте скобки:
ГДЕ Организация = &Орг И (Сумма > 1000 ИЛИ Проведён = ЛОЖЬ)
Когда в условии есть и И, и ИЛИ, расставляйте скобки всегда, даже если по приоритету они не обязательны. Явные скобки читаются однозначно и спасают при доработке запроса через полгода.
Оператор НЕ удобен для инверсии ПОДОБНО и В:
ГДЕ НЕ Номенклатура.Наименование ПОДОБНО "%образец%"
Отбор по тексту: оператор ПОДОБНО и спецсимволы
Для поиска по части строки используют ПОДОБНО (аналог 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. Вложенные ВЫБОР допустимы, но на третьем уровне вложенности запрос становится нечитаемым — такую логику проще вынести в соединение со вспомогательной таблицей значений.
Типичные ошибки и ускорение отбора
Ошибки, которые встречаются чаще всего:
- Сравнение с
NULLчерез=. ПишутПоле = NULLи удивляются пустому результату. ТолькоЕСТЬ NULL. - Нет скобок при смеси
ИиИЛИ. Запрос возвращает лишние строки из-за приоритетаИнадИЛИ. - Отбор по дате через
=. Документ с временем14:30не найдётся по= НачалоДня. Нужен диапазонМЕЖДУ. - Условие в
ГДЕвместо параметров виртуальной таблицы. Остатки читаются целиком, потом фильтруются — медленно на больших регистрах. ПОДОБНО "%текст%"по большому справочнику. Ведущий%отключает индекс.
Приёмы, которые ускоряют отбор:
- ✅ Ставьте условие как можно раньше — в параметры виртуальной таблицы, а не в итоговое
ГДЕ. - ✅ Сравнивайте индексированные поля (измерения регистров, ссылки). Отбор по неиндексированному реквизиту тянет полное сканирование.
- ✅ Не оборачивайте поле в функцию в условии:
ГОД(Дата) = 2026мешает индексу, аДата МЕЖДУ НачалоГода И КонецГода— нет. - ✅
ИЛИпо разным полям часто мешает оптимизатору; иногда быстрее объединить два запроса черезОБЪЕДИНИТЬ. - ✅ Проверяйте план и время на боевом объёме данных, а не на пустой демо-базе.
Перед тем как менять готовый отчёт или обработку с запросом в рабочей базе, сохраните исходный текст запроса. Неверно переставленная скобка в условии меняет цифры в отчёте, а заметить это можно не сразу.
Чем `<>` отличается от `!=` в запросе 1С?
<>. Символ != не поддерживается и вызывает синтаксическую ошибку при проверке запроса.Почему условие по дате ничего не находит?
= с датой без времени, а у документов время заполнено. Используйте диапазон Дата МЕЖДУ НачалоПериода И КонецПериода и функцию КОНЕЦПЕРИОДА для верхней границы.Как в условии проверить, что реквизит не заполнен?
Поле <> ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка). Если значение пришло из соединения и может отсутствовать — проверяйте Поле ЕСТЬ NULL.Можно ли в условии `В` подставить список из другого запроса?
В ставят либо перечисление значений в скобках, либо вложенный запрос, возвращающий одну колонку. Для иерархических справочников удобнее В ИЕРАРХИИ.Почему поиск `ПОДОБНО "%слово%"` работает медленно?
% в начале не может использовать индекс, и платформа перебирает всю таблицу. По возможности стройте шаблон от начала строки ("слово%") или ограничивайте выборку другими условиями.