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

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

Как проверить значение на NULL и НЕОПРЕДЕЛЕНО в запросе 1С

Способы проверки значений NULL и НЕОПРЕДЕЛЕНО в запросах 1С: ЕСТЬ NULL, ЕСТЬNULL, сравнение с НЕОПРЕДЕЛЕНО, типичные ошибки и готовые примеры кода.

Проверка на неопределённое значение — одна из самых частых задач при написании запросов в 1С. Проблема в том, что в платформе существует два похожих, но принципиально разных понятия: NULL — отсутствие значения в результате соединения таблиц, и НЕОПРЕДЕЛЕНО — специальное значение, которое может храниться в реквизите составного типа. Путаница между ними приводит к ошибкам «Невозможно сравнить поля» и к некорректным данным в отчётах.

Обычное сравнение «равно / не равно» с NULL в запросе не работает: любая операция сравнения с NULL возвращает не ИСТИНА и не ЛОЖЬ, а NULL, поэтому условие ГДЕ Товары.Поставщик = NULL не вернёт ни одной строки. Для корректной проверки язык запросов 1С предоставляет специальные конструкции — оператор ЕСТЬ NULL и функцию ЕСТЬNULL().

Ниже разобраны оба сценария: работа с NULL после левых соединений и проверка значения НЕОПРЕДЕЛЕНО в полях составного типа, а также типичные ошибки и способы контроля результата.

Чем NULL отличается от НЕОПРЕДЕЛЕНО

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

НЕОПРЕДЕЛЕНО — это вполне конкретное значение, которое платформа записывает в реквизит составного типа, когда пользователь или код явно очистил поле. Оно хранится в базе данных и участвует в сравнениях как обычное значение. Пустая ссылка справочника — тоже не NULL и не НЕОПРЕДЕЛЕНО, а отдельное значение, проверяемое через ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка).

Проверка на NULL через оператор ЕСТЬ NULL

Основной способ отбора строк с отсутствующими данными — предикат ЕСТЬ NULL (в английском синтаксисе IS NULL). Он пишется после имени поля без знака равенства:

ГДЕ

Продажи.Менеджер ЕСТЬ NULL

Для обратного условия — отобрать только строки, где данные есть, — используется отрицание НЕ:

ГДЕ

НЕ Продажи.Менеджер ЕСТЬ NULL

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

bsl
ВЫБРАТЬ
	Заказы.Ссылка КАК Заказ
ИЗ
	Документ.ЗаказПокупателя КАК Заказы
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ОплатаОтПокупателя КАК Оплаты
		ПО Заказы.Ссылка = Оплаты.Заказ
ГДЕ
	Оплаты.Ссылка ЕСТЬ NULL

Замена NULL значением по умолчанию через ЕСТЬNULL()

Часто NULL нужно не отфильтровать, а заменить осмысленным значением, чтобы отчёт не показывал пустые ячейки и чтобы вычисления не ломались. Для этого служит функция ЕСТЬNULL(ПроверяемоеПоле, ЗначениеЕслиNULL). Она возвращает поле, если оно не NULL, либо второй аргумент.

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

ВЫБРАТЬ

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

ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Товары.Ссылка = Остатки.Номенклатура

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

Проверка на значение НЕОПРЕДЕЛЕНО

Значение НЕОПРЕДЕЛЕНО сравнивается обычными операторами, потому что оно реально хранится в базе. Отбор выглядит так:

ГДЕ

Контрагенты.Регион = НЕОПРЕДЕЛЕНО

Такая ситуация возникает в реквизитах составного типа, когда полю присвоили «очищенное» состояние. На практике проверка на НЕОПРЕДЕЛЕНО часто комбинируется с проверкой на пустую ссылку, поскольку пользователь мог и очистить поле, и оставить в нём пустую ссылку справочника.

Если в одном запросе встречаются оба случая — NULL от соединения и НЕОПРЕДЕЛЕНО из данных, — условия складывают через ИЛИ:

ГДЕ

Данные.Поле ЕСТЬ NULL

ИЛИ Данные.Поле = НЕОПРЕДЕЛЕНО

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

Типичные ошибки
01
Сравнение Поле = NULL — условие никогда не выполняется, запрос молча возвращает пустой результат
02
Применение ЕСТЬNULL к значению НЕОПРЕДЕЛЕНО — функция его не обрабатывает, данные остаются «грязными»
03
Несовместимые типы аргументов ЕСТЬNULL — запрос падает с ошибкой при выполнении
04
Проверка только на NULL, когда в поле может лежать пустая ссылка — часть проблемных строк остаётся незамеченной

Конструкция ВЫБОР для сложных условий

Когда нужно не отфильтровать строки, а пометить их или подставить разные значения в зависимости от состояния поля, используется оператор ВЫБОР — аналог CASE из классического SQL. Он позволяет в одном выражении обработать и NULL, и НЕОПРЕДЕЛЕНО, и пустую ссылку:

ВЫБОР

КОГДА Остатки.КоличествоОстаток ЕСТЬ NULL

ТОГДА 0

КОГДА Остатки.КоличествоОстаток < 0

ТОГДА 0

ИНАЧЕ Остатки.КоличествоОстаток

КОНЕЦ КАК Остаток

Ветка ИНАЧЕ обязательна, если хотя бы теоретически возможна ситуация, не покрытая условиями, — иначе для таких строк результатом выражения снова станет NULL, и проблема вернётся на следующем уровне обработки.

Порядок действий при отладке
  1. 1
    Выполните запрос в консоли запросов без отборов и посмотрите, что реально приходит в проблемном поле: пустая ячейка (NULL), «<Неопределено>» или пустая ссылка
  2. 2
    Определите источник: NULL — ищите левое соединение или обращение к несуществующему реквизиту; НЕОПРЕДЕЛЕНО — проверяйте составной тип поля
  3. 3
    Для NULL добавьте ЕСТЬ NULL в отбор или ЕСТЬNULL в список полей; для НЕОПРЕДЕЛЕНО — обычное сравнение
  4. 4
    Повторно выполните запрос и проверьте, что количество строк и итоги соответствуют ожиданию

Проверка результата и контрольные точки

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

Дополнительный приём — временно вывести само проверяемое поле в результат запроса и посмотреть, как платформа отображает его значения. NULL обычно показывается как пустая ячейка без типа, НЕОПРЕДЕЛЕНО — с явной подписью, пустая ссылка — с типом справочника или документа.

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

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

Строки с отсутствующими связанными данными
Норма

Отбираются условием ЕСТЬ NULL или заменяются ЕСТЬNULL

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

Условие «= NULL» — строки не возвращаются вообще

Числовые итоги по соединённым таблицам
Норма

Суммы считаются, вместо пропусков стоят нули

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

Итоги занижены или содержат пропуски из-за NULL

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

Обработаны и НЕОПРЕДЕЛЕНО, и пустая ссылка

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

Проверяется только один вариант, часть данных теряется

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

Итог

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

NULL и НЕОПРЕДЕЛЕНО — разные сущности. NULL проверяется только через ЕСТЬ NULL и заменяется функцией ЕСТЬNULL, НЕОПРЕДЕЛЕНО — обычным сравнением. Сравнение с NULL через «=» — самая частая и самая коварная ошибка, потому что запрос не сообщает об ошибке, а просто возвращает пустой результат.

Почему условие «ГДЕ Поле = NULL» не работает?

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

Чем заменить NULL в числовом поле, чтобы итоги считались?

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

Как проверить поле одновременно на NULL и на пустую ссылку?

Объедините условия через ИЛИ: «Поле ЕСТЬ NULL ИЛИ Поле = ЗНАЧЕНИЕ(Справочник.ИмяСправочника.ПустаяСсылка)». Либо сначала оберните поле в ЕСТЬNULL с подстановкой пустой ссылки и сравнивайте уже результат.

Можно ли использовать ЕСТЬNULL для значения НЕОПРЕДЕЛЕНО?

Нет. ЕСТЬNULL реагирует только на NULL. Для НЕОПРЕДЕЛЕНО используйте конструкцию ВЫБОР КОГДА Поле = НЕОПРЕДЕЛЕНО ТОГДА ... ИНАЧЕ Поле КОНЕЦ.

Откуда берётся NULL, если соединений в запросе нет?

NULL появляется при обращении через точку к реквизиту ссылки составного типа, если у фактического объекта такого реквизита нет, а также при обращении к реквизиту документа в выборке по журналу, где этот реквизит определён не для всех видов документов.