Разработка и Конфигурация · 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 — синтаксическая ошибка.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка КАК Документ,
| Реализация.Контрагент КАК Контрагент
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| (&Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
| ИЛИ Реализация.Контрагент = &Контрагент)
| И (&ДатаНачала = ДАТАВРЕМЯ(1,1,1)
| ИЛИ Реализация.Дата >= &ДатаНачала)";
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);Параметр составного типа или Неопределено
Если параметр может быть не заполнен вовсе (в модуле ему не присвоили значение — Неопределено), запрос при выполнении выдаст ошибку о неверном типе параметра. Поэтому перед УстановитьПараметр значение нужно нормализовать: подставить пустую ссылку, пустую строку или дату по умолчанию.
Более надёжный приём для составных и смешанных сценариев — передать отдельный булев параметр-признак. Тогда условие становится явным и не зависит от «пустых» значений:
ГДЕ
(НЕ &ОтборПоКонтрагенту ИЛИ Таб.Контрагент = &Контрагент)
Запрос.УстановитьПараметр("ОтборПоКонтрагенту", ЗначениеЗаполнено(Контрагент));
Запрос.УстановитьПараметр("Контрагент", ?(ЗначениеЗаполнено(Контрагент), Контрагент, Справочники.Контрагенты.ПустаяСсылка()));Такой подход исключает неоднозначность: например, когда пустая строка — это легитимное значение отбора, а не признак «отбор не задан». С булевым флагом вы явно управляете логикой.
Проверка заполненности в СКД и динамических списках
В системе компоновки данных проверять параметр на пустоту в тексте запроса часто не нужно: отборы, добавленные пользователем, применяются только когда они включены. Но если отбор жёстко зашит в настройках, используется тот же шаблон сравнения с пустым значением в поле «Условие» связи параметра.
Для динамических списков с произвольным запросом действует то же правило: условие с параметром должно быть «самоотключающимся» через ИЛИ, иначе при незаполненном параметре список окажется пустым. Проверяйте поведение списка в обоих состояниях — с заданным и с пустым параметром.
Способы проверки заполненности
Подходит для однотипных параметров: ссылок, строк, дат, чисел. Ограничение: нужно точно знать тип и правильное пустое значение.
Подходит для составных типов и случаев, где пустое значение может быть легитимным. Требует дополнительной строки кода при установке параметров.
Единственный способ проверить NULL в результате соединений и реквизитах составного типа. Для параметров запроса обычно не применяется.
Типичные ошибки и как их избежать
Самая частая ошибка — сравнение с NULL через равенство: ГДЕ &Параметр = NULL. Такое условие никогда не истинно, запрос отработает без ошибки, но вернёт пустой результат, и причину бывает трудно найти.
Вторая ошибка — несовпадение вида пустой ссылки: параметр типа «Справочник.Контрагенты», а в условии написано ЗНАЧЕНИЕ(Справочник.Партнеры.ПустаяСсылка). Сравнение ссылок разных видов всегда ложно, и отбор «молча» перестаёт работать. Третья — проверка строки пробелами: строка из одного пробела не равна пустой строке, поэтому при необходимости нормализуйте значение через СокрЛП до передачи в запрос.
Как проверить, что условие работает правильно
Проверку выполняйте в три шага: сначала выполните запрос с пустым параметром — должны вернуться все строки без отбора. Затем с заполненным — только строки, соответствующие отбору. Наконец, с граничным значением (пробел в строке, дата 01.01.0001), чтобы убедиться, что логика не ломается.
Как проверить результат
Запрос возвращает полную выборку без отбора
Выборка пустая — условие сравнения неверно или тип пустого значения не совпадает
Возвращаются только строки, соответствующие отбору
Возвращаются все строки — ветка ИЛИ срабатывает всегда, проверьте вид пустой ссылки
Запрос выполняется без ошибок при обоих состояниях параметра
Ошибка типа параметра — в параметр попало Неопределено или значение другого типа
Удобно отлаживать такие условия в консоли запросов: меняйте значение параметра прямо в консоли и наблюдайте, как меняется результат. Это быстрее, чем правка модуля и перезапуск формы.
Что важно запомнить
Проверка «параметр заполнен» в запросе 1С — это сравнение с пустым значением конкретного типа через шаблон «пусто ИЛИ совпадает». NULL проверяется только через ЕСТЬ NULL, а для составных типов надёжнее передавать отдельный булев признак. Всегда тестируйте запрос с пустым и заполненным параметром.
Частые вопросы
Можно ли использовать ЗначениеЗаполнено() в тексте запроса?
Нет. Эта функция доступна только во встроенном языке. В запросе проверку выполняйте сравнением с пустым значением типа или через ЕСТЬ NULL, а при необходимости вычислите ЗначениеЗаполнено() в коде и передайте результат булевым параметром.
Чем отличается NULL от пустой ссылки?
Пустая ссылка — реальное значение ссылочного типа, с ней работает обычное сравнение. NULL — признак отсутствия значения (результат соединений, незаполненный составной реквизит), он не равен ничему и проверяется только оператором ЕСТЬ NULL.
Как проверить, что параметр-список (массив) не пустой?
Передайте отдельный булев параметр, вычисленный в коде как Массив.Количество() > 0, и используйте его в условии: (НЕ &ЕстьОтбор ИЛИ Таб.Поле В (&Список)). Пустой массив в условии В приведёт к пустому результату.
Почему условие с ИЛИ замедляет запрос?
Конструкция «параметр пуст ИЛИ поле = параметр» может мешать оптимизатору использовать индекс. На больших таблицах иногда выгоднее формировать два разных текста запроса в коде — с отбором и без — и выполнять нужный.
Как задать пустую дату в параметре?
В коде используйте '00010101' (или Дата(1,1,1)), а в тексте запроса сравнивайте с ДАТАВРЕМЯ(1,1,1). Передавать Неопределено вместо даты нельзя — запрос завершится ошибкой типа параметра.