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

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

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

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

Условие в запросе 1С — это способ отобрать только те записи, которые нужны для отчёта, обработки или динамического списка. Платформа «1С:Предприятие» использует собственный язык запросов, похожий на SQL, но с рядом особенностей: виртуальными таблицами, параметрами через амперсанд и конструкцией ВЫБОР вместо CASE. Понимание этих особенностей позволяет писать быстрые запросы, которые корректно работают на любых объёмах данных.

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

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

Базовый синтаксис условия ГДЕ

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

Несколько условий объединяются логическими операторами И и ИЛИ, порядок вычисления задаётся скобками. Без скобок оператор И выполняется раньше, чем ИЛИ, что часто приводит к неверным результатам. Правило простое: при смешивании И и ИЛИ всегда расставляйте скобки явно.

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

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

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

И (Товары.ЗакупочнаяЦена МЕЖДУ &ЦенаОт И &ЦенаДо)

И НЕ Товары.ПометкаУдаления

Условия через параметры запроса

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

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

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

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

"ВЫБРАТЬ

| Реализация.Ссылка,

| Реализация.СуммаДокумента

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Контрагент = &Контрагент

| И Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода";

Запрос.УстановитьПараметр("Контрагент", ВыбранныйКонтрагент);

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала));

Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаОкончания));

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

Обратите внимание на границы периода: если поле Дата хранит время, условие «МЕЖДУ началом и концом» без КонецДня отсечёт документы, созданные в течение последнего дня. Это классическая ошибка, из-за которой отчёты «теряют» данные.

Условие ВЫБОР для вычисляемых полей

Конструкция ВЫБОР — аналог CASE в SQL. Она не фильтрует записи, а вычисляет значение поля в зависимости от условия. Типичное применение — вывести текстовый статус документа, рассчитать признак просрочки или подставить разные поля в зависимости от вида операции.

ВЫБРАТЬ

Заказ.Ссылка,

ВЫБОР

КОГДА Заказ.Проведен

ТОГДА "Проведён"

КОГДА Заказ.ПометкаУдаления

ТОГДА "Удалён"

ИНАЧЕ "Черновик"

КОНЕЦ КАК Статус

ИЗ

Документ.ЗаказПокупателя КАК Заказ

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

Сравнение вариантов размещения логики помогает выбрать правильный инструмент:

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

Секция ГДЕ

Отбирает записи до выборки. Подходит для фильтрации по полям таблицы и параметрам; работает быстрее всего при наличии индексов.

Конструкция ВЫБОР

Вычисляет значение поля для каждой строки. Подходит для статусов, признаков и подстановок, но не сокращает число записей.

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

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

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

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

ВЫБРАТЬ

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

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

ИЗ

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

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

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

И Номенклатура В (&СписокТоваров)) КАК Остатки

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

Работа со списками, NULL и строками

Отбор по списку значений выполняется оператором В. В параметр передаётся массив или список значений: ГДЕ Товар.ВидНоменклатуры В (&СписокВидов). Для иерархических справочников используйте оператор В ИЕРАРХИИ — он отберёт элементы указанной группы и всех её подгрупп без рекурсивных обходов в коде.

Проверка на NULL выполняется только операторами ЕСТЬ NULL и НЕ ЕСТЬ NULL. Сравнение «= NULL» всегда ложно и молча возвращает пустой результат — это ловушка для тех, кто пришёл из других языков. NULL часто появляется при левых соединениях, когда в присоединяемой таблице нет подходящей записи.

Поиск по подстроке выполняется оператором ПОДОБНО с символами шаблона: % — любая последовательность символов, _ — один символ. Пример: ГДЕ Контрагент.Наименование ПОДОБНО "%Ромашка%". Учтите, что поиск с шаблоном в начале строки не использует индекс и на больших таблицах работает медленно.

Порядок действий при написании условия
  1. 1
    Определите, что фильтруете: записи таблицы, итоги регистра или значения вычисляемого поля
  2. 2
    Для таблицы используйте ГДЕ, для итогов регистра — параметры виртуальной таблицы, для вычислений — ВЫБОР
  3. 3
    Вынесите изменяемые значения в параметры через &Имя и установите их методом УстановитьПараметр
  4. 4
    Проверьте запрос в консоли запросов на реальных данных, включая граничные случаи: пустой список, NULL, границы периода
  5. 5
    Сравните количество записей и контрольные суммы с ожидаемыми

Типичные ошибки и проверка результата

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

Типичные ошибки
01
Сравнение поля со значением другого типа (ссылка со строкой) — запрос возвращает пустой результат без сообщения об ошибке
02
Сравнение «= NULL» вместо ЕСТЬ NULL — условие никогда не выполняется, записи теряются
03
Условие по измерениям регистра в ГДЕ вместо параметров виртуальной таблицы — резкое падение производительности
04
Период без КонецДня для полей с временем — документы последнего дня не попадают в выборку
05
Смешение И и ИЛИ без скобок — логика отбора отличается от задуманной
06
Неустановленный параметр — запрос падает с ошибкой в момент выполнения

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

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

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

Количество записей в выборке
Норма

Совпадает с ручным подсчётом по списку в режиме предприятия

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

Записей меньше или больше ожидаемого — проверяйте условия по одному

Границы периода
Норма

Документы первого и последнего дня периода присутствуют

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

Крайние даты отсутствуют — проверьте НачалоДня/КонецДня

Значения вычисляемых полей ВЫБОР
Норма

Каждая ветка условия встречается в данных и даёт ожидаемое значение

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

Все строки получили значение ИНАЧЕ или NULL — условие не срабатывает

Время выполнения запроса
Норма

Запрос выполняется за секунды на рабочей базе

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

Запрос «висит» — условие размещено не там или нет индекса по полю отбора

FAQ

Чем ГДЕ отличается от ИМЕЮЩИЕ в запросе 1С?

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

Как задать условие «пустая ссылка»?

Используйте функцию ЗНАЧЕНИЕ с пустой ссылкой нужного типа: ГДЕ Документ.Договор = ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка). Альтернатива — передать пустую ссылку через параметр, получив её методом Справочники.ДоговорыКонтрагентов.ПустаяСсылка().

Можно ли использовать условие в соединении таблиц?

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

Как отобрать записи, где строковое поле не заполнено?

Проверяйте равенство пустой строке: ГДЕ Контрагент.ИНН = "". Для полей неограниченной длины и строк, которые могут быть NULL после соединений, добавьте проверку ЕСТЬ NULL через ИЛИ, иначе часть записей не попадёт в результат.

Почему условие по дате не отбирает документы последнего дня?

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

Итог

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

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