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

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

Условие в запросе 1С, когда параметр заполнен: синтаксис и примеры

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

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

Сложность в том, что «не заполнен» в 1С может означать разное: NULL, пустая ссылка справочника или документа, пустая строка, неопределённая дата, ноль для числа. Универсального условия «заполнен» в языке запросов нет — нужно сравнивать параметр с конкретным «пустым» значением его типа.

Что считается «пустым» значением в запросе 1С

Прежде чем писать условие, определите тип параметра и его «пустое» состояние. Для ссылочных типов это пустая ссылка конкретного вида: ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка). Для строки — пустая строка "", для даты — ДАТАВРЕМЯ(1,1,1), для числа — 0, для булево — ЛОЖЬ.

Отдельный случай — NULL. Он появляется не из параметра, а из результата соединения таблиц (например, левого соединения без пары) или из реквизита составного типа, где значение не задано. NULL не равен ничему, даже самому себе, поэтому сравнивать его через = бессмысленно — только через ЕСТЬ NULL / НЕ ЕСТЬ NULL.

Базовые условия проверки заполненности по типам

Классический шаблон «применить отбор, только если параметр заполнен» выглядит так:

ГДЕ

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

ИЛИ Таб.Контрагент = &Контрагент)

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

  • Строка: &Наименование = "" ИЛИ Таб.Наименование ПОДОБНО "%" + &Наименование + "%"
  • Дата: &ДатаНачала = ДАТАВРЕМЯ(1,1,1) ИЛИ Таб.Дата >= &ДатаНачала
  • Число: &Сумма = 0 ИЛИ Таб.Сумма >= &Сумма

Для проверки поля результата запроса на NULL используйте: ГДЕ Таб.Реквизит ЕСТЬ NULL (не заполнен) или ГДЕ НЕ Таб.Реквизит ЕСТЬ NULL (заполнен). Обратите внимание: конструкция НЕ ... ЕСТЬ NULL корректна, а ЕСТЬ НЕ NULL — синтаксическая ошибка.

bsl
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка КАК Документ,
| Реализация.Контрагент КАК Контрагент
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| (&Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
| ИЛИ Реализация.Контрагент = &Контрагент)
| И (&ДатаНачала = ДАТАВРЕМЯ(1,1,1)
| ИЛИ Реализация.Дата >= &ДатаНачала)";
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);

Параметр составного типа или Неопределено

Если параметр может быть не заполнен вовсе (в модуле ему не присвоили значение — Неопределено), запрос при выполнении выдаст ошибку о неверном типе параметра. Поэтому перед УстановитьПараметр значение нужно нормализовать: подставить пустую ссылку, пустую строку или дату по умолчанию.

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

ГДЕ

(НЕ &ОтборПоКонтрагенту ИЛИ Таб.Контрагент = &Контрагент)

bsl
Запрос.УстановитьПараметр("ОтборПоКонтрагенту", ЗначениеЗаполнено(Контрагент));
Запрос.УстановитьПараметр("Контрагент", ?(ЗначениеЗаполнено(Контрагент), Контрагент, Справочники.Контрагенты.ПустаяСсылка()));

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

Проверка заполненности в СКД и динамических списках

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

Для динамических списков с произвольным запросом действует то же правило: условие с параметром должно быть «самоотключающимся» через ИЛИ, иначе при незаполненном параметре список окажется пустым. Проверяйте поведение списка в обоих состояниях — с заданным и с пустым параметром.

Способы проверки заполненности

Сравнение с пустым значением

Подходит для однотипных параметров: ссылок, строк, дат, чисел. Ограничение: нужно точно знать тип и правильное пустое значение.

Булев параметр-признак

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

ЕСТЬ NULL

Единственный способ проверить NULL в результате соединений и реквизитах составного типа. Для параметров запроса обычно не применяется.

Типичные ошибки и как их избежать

Самая частая ошибка — сравнение с NULL через равенство: ГДЕ &Параметр = NULL. Такое условие никогда не истинно, запрос отработает без ошибки, но вернёт пустой результат, и причину бывает трудно найти.

Вторая ошибка — несовпадение вида пустой ссылки: параметр типа «Справочник.Контрагенты», а в условии написано ЗНАЧЕНИЕ(Справочник.Партнеры.ПустаяСсылка). Сравнение ссылок разных видов всегда ложно, и отбор «молча» перестаёт работать. Третья — проверка строки пробелами: строка из одного пробела не равна пустой строке, поэтому при необходимости нормализуйте значение через СокрЛП до передачи в запрос.

Типичные ошибки
01
Сравнение параметра с NULL через «=» — условие всегда ложно, результат пустой без сообщения об ошибке. Используйте ЕСТЬ NULL.
02
Пустая ссылка другого вида справочника — отбор не срабатывает. Сверяйте тип параметра и тип в ЗНАЧЕНИЕ(...).
03
Передача Неопределено в параметр — ошибка выполнения запроса. Нормализуйте значение перед УстановитьПараметр.
04
Проверка строки только на "" — строка из пробелов считается заполненной. Применяйте СокрЛП до передачи параметра.

Как проверить, что условие работает правильно

Проверку выполняйте в три шага: сначала выполните запрос с пустым параметром — должны вернуться все строки без отбора. Затем с заполненным — только строки, соответствующие отбору. Наконец, с граничным значением (пробел в строке, дата 01.01.0001), чтобы убедиться, что логика не ломается.

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

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

Параметр пустой
Норма

Запрос возвращает полную выборку без отбора

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

Выборка пустая — условие сравнения неверно или тип пустого значения не совпадает

Параметр заполнен
Норма

Возвращаются только строки, соответствующие отбору

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

Возвращаются все строки — ветка ИЛИ срабатывает всегда, проверьте вид пустой ссылки

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

Запрос выполняется без ошибок при обоих состояниях параметра

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

Ошибка типа параметра — в параметр попало Неопределено или значение другого типа

Удобно отлаживать такие условия в консоли запросов: меняйте значение параметра прямо в консоли и наблюдайте, как меняется результат. Это быстрее, чем правка модуля и перезапуск формы.

Итог

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

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

Частые вопросы

Можно ли использовать ЗначениеЗаполнено() в тексте запроса?

Нет. Эта функция доступна только во встроенном языке. В запросе проверку выполняйте сравнением с пустым значением типа или через ЕСТЬ NULL, а при необходимости вычислите ЗначениеЗаполнено() в коде и передайте результат булевым параметром.

Чем отличается NULL от пустой ссылки?

Пустая ссылка — реальное значение ссылочного типа, с ней работает обычное сравнение. NULL — признак отсутствия значения (результат соединений, незаполненный составной реквизит), он не равен ничему и проверяется только оператором ЕСТЬ NULL.

Как проверить, что параметр-список (массив) не пустой?

Передайте отдельный булев параметр, вычисленный в коде как Массив.Количество() > 0, и используйте его в условии: (НЕ &ЕстьОтбор ИЛИ Таб.Поле В (&Список)). Пустой массив в условии В приведёт к пустому результату.

Почему условие с ИЛИ замедляет запрос?

Конструкция «параметр пуст ИЛИ поле = параметр» может мешать оптимизатору использовать индекс. На больших таблицах иногда выгоднее формировать два разных текста запроса в коде — с отбором и без — и выполнять нужный.

Как задать пустую дату в параметре?

В коде используйте '00010101' (или Дата(1,1,1)), а в тексте запроса сравнивайте с ДАТАВРЕМЯ(1,1,1). Передавать Неопределено вместо даты нельзя — запрос завершится ошибкой типа параметра.