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