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

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

1С: выбор когда есть NULL — проверка NULL в запросах

Как проверить NULL в запросе 1С: конструкция ВЫБОР КОГДА ЕСТЬ NULL, функция ЕСТЬNULL, типичные ошибки при соединениях и сравнениях. Примеры кода и проверка результата.

Значение NULL в запросах 1С появляется всякий раз, когда соединение таблиц не нашло пару: например, у номенклатуры нет цены в регистре или у контрагента не заполнен договор. Если не обработать такие случаи, в отчёте появятся пустые колонки, а сравнение «поле = значение» молча отфильтрует нужные строки, потому что NULL не равен ничему, даже самому себе.

Основной инструмент обработки — конструкция ВЫБОР КОГДА ... ЕСТЬ NULL ТОГДА ... КОНЕЦ и функция ЕСТЬNULL(). Первая позволяет строить произвольные условия с несколькими ветвями, вторая — быстро подставить значение по умолчанию вместо NULL. Ниже разобраны синтаксис, типовые сценарии, отличия от похожих конструкций и ошибки, которые чаще всего допускают разработчики.

Что такое NULL в запросах 1С и откуда он берётся

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

Критичное свойство NULL — трёхзначная логика. Любое сравнение с NULL (=, <>, >) возвращает не ИСТИНА и не ЛОЖЬ, а неопределённость, которая в условии ГДЕ трактуется как отсев строки. Поэтому условие ГДЕ Цены.Цена <> 0 исключит не только нулевые цены, но и все товары без цены вообще — часто это неожиданно и приводит к потере данных в отчётах.

Синтаксис ВЫБОР КОГДА ЕСТЬ NULL

Конструкция ВЫБОР — аналог CASE в других СУБД. Общий вид проверки на NULL:

ВЫБОР

КОГДА Цены.Цена ЕСТЬ NULL

ТОГДА 0

ИНАЧЕ Цены.Цена

КОНЕЦ КАК Цена

Ветвей КОГДА может быть несколько, что позволяет обрабатывать сложные сценарии: например, различать «цены нет вообще» и «цена есть, но нулевая»:

ВЫБОР

КОГДА Цены.Цена ЕСТЬ NULL

ТОГДА "Цена не назначена"

КОГДА Цены.Цена = 0

ТОГДА "Нулевая цена"

ИНАЧЕ "ОК"

КОНЕЦ КАК СтатусЦены

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

bsl
ВЫБОР
	КОГДА Цены.Цена ЕСТЬ NULL
		ТОГДА 0
	ИНАЧЕ Цены.Цена
КОНЕЦ КАК Цена

Функция ЕСТЬNULL как короткая альтернатива

Когда нужно просто заменить NULL значением по умолчанию, компактнее использовать функцию ЕСТЬNULL(ПроверяемоеЗначение, ЗначениеЕслиNULL). Запись ЕСТЬNULL(Цены.Цена, 0) эквивалентна приведённому выше ВЫБОРу, но короче и легче читается в длинных списках полей.

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

Сравнение вариантов

ВЫБОР КОГДА ЕСТЬ NULL

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

ЕСТЬNULL(поле, значение)

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

Условие ГДЕ поле ЕСТЬ NULL

Фильтрация строк без значения (или НЕ ЕСТЬ NULL — только заполненные). Не подставляет значение, а отбирает записи.

Проверка NULL в условии ГДЕ и при соединениях

Для отбора строк используется оператор ЕСТЬ NULL прямо в секции ГДЕ или в условии соединения. Типовая задача — найти товары, для которых не установлена цена:

ВЫБРАТЬ

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

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены

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

ГДЕ

Цены.Цена ЕСТЬ NULL

Обратная задача — оставить только строки с заполненным значением — решается через НЕ ЕСТЬ NULL. Важно помнить: если та же проверка нужна в условии соединения, её место — в секции ПО, а не в ГДЕ, иначе левое соединение фактически превратится во внутреннее и потеряет смысл.

Типичные ошибки при работе с NULL

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

Вторая ошибка — обработка NULL только в полях ВЫБРАТЬ, но не в итогах и группировках. При группировке NULL образует отдельную группу, а агрегатные функции (кроме КОЛИЧЕСТВО(*)) игнорируют NULL-значения, что искажает средние и суммы, если разработчик рассчитывал на ноль. Третья ошибка — смешение NULL с пустой ссылкой или пустой строкой: это разные значения, и проверка ЕСТЬ NULL не отловит пустую ссылку, а сравнение с пустой ссылкой не отловит NULL.

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

Проверка результата и отладка запроса

После добавления обработки NULL запрос стоит проверить на данных, где проблема гарантированно есть. Практичный способ — временно вывести поле в трёх видах: как есть, через ЕСТЬNULL и через ВЫБОР с текстовой меткой. Тогда сразу видно, какие строки содержали NULL и как их обработала конструкция.

Удобно использовать консоль запросов: выполнить запрос без обработки, посчитать количество строк с NULL через условие ГДЕ поле ЕСТЬ NULL, затем применить обработку и убедиться, что итоговое число строк не изменилось (если отбор не предполагался), а значения подставились корректно. Для отчётов на СКД дополнительно проверяйте ресурсы: вычисляемые поля с ЕСТЬNULL должны попадать в итоги без отдельной группы «пусто».

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

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

Количество строк до и после добавления ЕСТЬNULL
Норма

Число строк не изменилось, изменились только значения колонки

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

Строки пропали — вероятно, проверка попала в ГДЕ и отфильтровала записи

Значение колонки в строках без данных
Норма

Подставлено значение по умолчанию (0, пустая ссылка, текст)

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

Колонка по-прежнему пустая или содержит NULL в итогах

Группировки и итоги отчёта
Норма

Нет отдельной строки с пустыми измерениями

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

Появилась группа с незаполненными полями — NULL не обработан до группировки

Границы применения и производительность

ЕСТЬNULL и ВЫБОР — недорогие операции, но массовое применение ЕСТЬNULL к полям соединения в условии ПО может мешать оптимизатору СУБД использовать индексы. Правильнее проектировать соединения так, чтобы проверки на NULL выполнялись уже над результатом, а не над ключами связи.

В виртуальных таблицах (срезы последних, остатки) NULL в полях ресурсов встречается редко — чаще отсутствует сама строка, поэтому обработку NULL логично размещать после левого соединения с виртуальной таблицей, а не внутри её параметров. Также помните, что в СКД часть подстановок значений можно выполнить на закладке «Настройки» через выражения представления, не меняя текст запроса.

Маршрут решения

Как выбрать действие

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

FAQ

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

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

Чем ЕСТЬNULL отличается от ВЫБОР КОГДА ЕСТЬ NULL?

ЕСТЬNULL(поле, значение) — короткая функция для одной подстановки значения по умолчанию. ВЫБОР нужен, когда условий несколько или логика сложнее простой замены. По результату простые случаи эквивалентны.

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

Используйте «поле НЕ ЕСТЬ NULL». Если нужно отсечь ещё и пустые ссылки, добавьте условие «И поле <> ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка)», так как пустая ссылка и NULL — разные значения.

Почему после добавления проверки в ГДЕ левое соединение перестало работать?

Условие на поле правой таблицы в секции ГДЕ отсекает строки, где соединение не нашло пару. Перенесите условие в секцию ПО соединения или добавьте ветку «ИЛИ поле ЕСТЬ NULL».

Как NULL влияет на СУММУ и СРЕДНЕЕ в запросе?

Агрегатные функции игнорируют NULL-значения: СРЕДНЕЕ посчитается только по заполненным строкам, что завысит результат, если вы ожидали ноль вместо отсутствующих данных. Обработайте поле через ЕСТЬNULL до группировки.

Можно ли использовать ЕСТЬNULL в СКД?

Да, функция доступна в тексте запроса набора данных и в выражениях вычисляемых полей СКД. Для части задач подстановки представления вместо изменения запроса можно использовать настройки полей на соответствующих закладках конструктора.

Итог

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

NULL проверяется только оператором ЕСТЬ NULL, никогда — сравнением. Для подстановки значения используйте ЕСТЬNULL или ВЫБОР КОГДА ЕСТЬ NULL с обязательной ветвью ИНАЧЕ. Следите, чтобы проверки в ГДЕ не уничтожали эффект левого соединения, и не путайте NULL с пустой ссылкой и нулём.