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

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

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

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

В языке запросов 1С нет единого понятия «пустое значение» — в зависимости от типа поля используются разные конструкции: NULL, пустая ссылка, пустая строка, пустая дата или неопределённое значение составного типа. Если перепутать эти варианты, запрос либо вернёт не те строки, либо не вернёт ничего, и ошибку бывает трудно заметить, потому что синтаксис при этом корректен.

Чаще всего задача возникает в трёх ситуациях: нужно отобрать записи, где реквизит не заполнен; нужно передать в параметр пустое значение из кода; нужно корректно обработать NULL, который появляется при соединениях таблиц. Каждая ситуация решается своим способом, и ниже они разобраны отдельно с примерами текста запроса.

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

NULL в 1С — это отсутствие значения как такового. Он появляется не потому, что пользователь не заполнил реквизит, а в результате левого или правого соединения таблиц, обращения к реквизиту через точку у NULL-ссылки, а также при обращении к измерениям виртуальных таблиц, где записи нет. Для реквизита, который просто не заполнен в карточке объекта, в базе хранится не NULL, а значение по умолчанию для типа этого реквизита.

Значения по умолчанию зависят от типа: для ссылочных типов это пустая ссылка конкретного вида (например, пустая ссылка справочника «Номенклатура»), для строки — пустая строка, для числа — ноль, для даты — 01.01.0001 00:00:00, для булево — Ложь. Поэтому условие «реквизит не заполнен» почти всегда означает сравнение с одним из этих значений, а не с NULL.

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

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

Для ссылочных реквизитов используется функция ЗНАЧЕНИЕ() с указанием пустой ссылки нужного типа. Тип должен точно совпадать с типом реквизита, иначе условие ничего не найдёт.

ВЫБРАТЬ

Номенклатура.Ссылка КАК Ссылка

ИЗ

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

ГДЕ

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

Этот запрос вернёт элементы справочника, у которых не указана группа. Если реквизит составного типа — например, может хранить ссылку на контрагента или на физическое лицо, — потребуется проверка на пустые ссылки всех возможных типов через ИЛИ, либо более надёжный приём: сравнение с НЕОПРЕДЕЛЕНО не сработает в запросе, поэтому на практике составные реквизиты часто приводят к одному типу через ВЫРАЗИТЬ и сравнивают с пустой ссылкой этого типа.

Для перечислений синтаксис аналогичен: ГДЕ СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.ПустаяСсылка). Для планов счетов, планов видов характеристик и других ссылочных объектов — тот же шаблон с именем соответствующего объекта метаданных.

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

Для строкового реквизита условие выглядит как сравнение с пустой строкой: ГДЕ Товары.Комментарий = "". Учтите нюанс: если в реквизит записали строку из пробелов, она не равна пустой строке, и такие записи условие не отберёт. При необходимости строку обрезают функцией сокращения пробелов на стороне кода или фильтруют дополнительно.

Для даты пустым значением считается начало отсчёта: ГДЕ Документ.ДатаОплаты = ДАТАВРЕМЯ(1,1,1). Функция ДАТАВРЕМЯ принимает год, месяц, день и опционально время; ДАТАВРЕМЯ(1,1,1) соответствует 01.01.0001 00:00:00. Для числа пустым значением фактически является ноль: ГДЕ Товар.Количество = 0 — отдельного «пустого числа» в 1С не существует.

СсылкаЗНАЧЕНИЕ(...ПустаяСсылка)

Тип должен совпадать с типом реквизита

Строка""

Строка из пробелов не считается пустой

ДатаДАТАВРЕМЯ(1,1,1)

Соответствует 01.01.0001 00:00:00

Число0

Отдельного пустого числа нет

NULLЕСТЬ NULL

Сравнение через = NULL не работает

Как работать с NULL: ЕСТЬ NULL и ЕСТЬNULL()

Оператор ЕСТЬ NULL применяется там, где NULL реально может появиться — прежде всего после левых соединений. Типовой пример: найти контрагентов, по которым не было заказов.

ВЫБРАТЬ

Контрагенты.Ссылка КАК Контрагент

ИЗ

Справочник.Контрагенты КАК Контрагенты

ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказПокупателя КАК Заказы

ПО Заказы.Контрагент = Контрагенты.Ссылка

ГДЕ

Заказы.Ссылка ЕСТЬ NULL

Обратная проверка — НЕ Поле ЕСТЬ NULL или Поле ЕСТЬ НЕ NULL — отбирает строки, где значение присутствует. Это стандартный способ отфильтровать «пустые» строки результата соединения.

Функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) заменяет NULL на указанное значение прямо в выборке. Например, ЕСТЬNULL(Остатки.Количество, 0) вернёт ноль вместо NULL для товаров без остатка, что избавляет от ошибок при последующих вычислениях и выводе в отчёт. Второй аргумент должен быть совместим по типу с ожидаемым результатом.

Как передать пустое значение через параметр запроса

Когда значение приходит из кода, его передают через параметр. Главное правило: параметр должен быть типизированным. Если написать Запрос.УстановитьПараметр("Контрагент", Неопределено), запрос с условием Контрагент = &Контрагент не отберёт записи с пустой ссылкой — Неопределено и пустая ссылка не равны.

Правильный вариант — передать именно пустую ссылку нужного типа:

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

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

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

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

Запрос.УстановитьПараметр("Контрагент",

Справочники.Контрагенты.ПустаяСсылка());

Для даты передают Дата(1,1,1), для строки — пустую строку, для числа — 0. Если параметр должен означать «отбор не применяется», лучше не подставлять пустое значение, а строить условие вида ГДЕ (&Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) ИЛИ Контрагент = &Контрагент), либо формировать текст запроса динамически.

Порядок действий при отборе по незаполненному реквизиту
  1. 1
    Определите тип реквизита в конфигураторе — ссылочный, строка, дата, число или составной
  2. 2
    Для ссылочного типа напишите условие с ЗНАЧЕНИЕ(Вид.Имя.ПустаяСсылка) точно того же типа
  3. 3
    Для строки, даты и числа используйте "", ДАТАВРЕМЯ(1,1,1) и 0 соответственно
  4. 4
    Если поле участвует в левом соединении — добавьте проверку ЕСТЬ NULL
  5. 5
    Выполните запрос в консоли запросов и убедитесь, что отобраны именно записи с незаполненным полем

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

Самая распространённая ошибка — сравнение с NULL через равенство. Запрос выполняется без сообщения об ошибке, но результат пустой, и причина неочевидна. Вторая частая ошибка — несовпадение типа пустой ссылки: реквизит имеет тип «Справочник.Контрагенты», а в условии указана пустая ссылка другого справочника. Такое условие просто ничего не найдёт.

Третья группа ошибок связана с составными типами. Если реквизит составной и в нём лежит пустая ссылка одного из типов, сравнение с пустой ссылкой другого типа не сработает. Проверять нужно либо все допустимые типы, либо приводить значение через ВЫРАЗИТЬ.

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

Для диагностики удобно выполнить запрос в консоли запросов и посмотреть, что фактически лежит в поле: выведите поле в выборку без отбора и проверьте представление значений. Пустая ссылка отображается как пустое представление объекта, NULL — обычно помечается отдельно в консоли. После этого станет ясно, какое именно «пустое» значение нужно отбирать.

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

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

Запрос с условием на пустое значение
Норма

Возвращаются записи, где реквизит визуально не заполнен

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

Пустой результат при заведомо незаполненных реквизитах — проверьте тип пустой ссылки

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

NULL отфильтрован оператором ЕСТЬ NULL

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

Сравнение через = NULL, строки теряются

Параметр из кода
Норма

Передана типизированная пустая ссылка или Дата(1,1,1)

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

Передано Неопределено — отбор не срабатывает

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

Чем отличается NULL от пустой ссылки в запросе 1С?

NULL означает отсутствие значения и возникает при соединениях таблиц и обращениях к несуществующим данным. Пустая ссылка — это конкретное типизированное значение, которое хранится в незаполненном ссылочном реквизите. Они не равны друг другу, и проверяются разными способами: NULL — оператором ЕСТЬ NULL, пустая ссылка — сравнением с ЗНАЧЕНИЕ(...ПустаяСсылка).

Почему условие «Поле = NULL» не возвращает записи?

Любое сравнение с NULL даёт неопределённый результат, а не Истину, поэтому такие строки не попадают в выборку. Это стандартное поведение SQL-подобных языков. Вместо равенства используйте конструкцию «Поле ЕСТЬ NULL».

Как в запросе заменить пустую ссылку на текст «Не указано»?

Через конструкцию ВЫБОР: ВЫБОР КОГДА Поле = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) ТОГДА "Не указано" ИНАЧЕ ... КОНЕЦ. Функция ЕСТЬNULL здесь не поможет, так как она обрабатывает только NULL, а не пустые ссылки.

Как отобрать документы, у которых не заполнен составной реквизит?

Проверьте равенство пустым ссылкам всех типов, входящих в составной тип, объединив условия через ИЛИ. Альтернатива — привести поле к одному типу функцией ВЫРАЗИТЬ и сравнить с пустой ссылкой этого типа, что часто удобнее и быстрее.

Можно ли передать NULL в параметр запроса?

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

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

Сравните поле с ДАТАВРЕМЯ(1,1,1) — это значение соответствует пустой дате 01.01.0001. Из кода в параметр передавайте Дата(1,1,1). Если поле может содержать NULL из-за соединения, дополнительно добавьте проверку ЕСТЬ NULL.

Итог

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

Пустое значение в запросе 1С зависит от типа поля: для ссылок — ЗНАЧЕНИЕ(...ПустаяСсылка), для строк — "", для дат — ДАТАВРЕМЯ(1,1,1), для чисел — 0, а NULL проверяется только оператором ЕСТЬ NULL. Из кода в параметры передавайте типизированные пустые значения, а не Неопределено. Если отбор не срабатывает — сначала проверьте тип пустой ссылки и наличие NULL после соединений.