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

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

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

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

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

Для корректной работы с NULL в языке запросов 1С предусмотрены специальные конструкции: оператор «ЕСТЬ NULL» (IS NULL) для проверки и функция «ЕСТЬNULL» (ISNULL) для замены отсутствующего значения на конкретное. Ниже разобраны оба подхода с примерами, приведены типичные сценарии — от простого условия в секции ГДЕ до обработки NULL в СКД и в коде на встроенном языке, а также ошибки, которые приводят к неверным итогам и потерянным строкам в отчётах.

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

NULL — это не пустая строка, не ноль и не пустая ссылка. Это отдельный маркер отсутствия значения, и сравнение NULL с чем бы то ни было (включая другой NULL) через обычные операторы сравнения всегда даёт ложь. Поэтому условие «ГДЕ Остаток = NULL» тихо отфильтрует все строки, и запрос вернёт пустой результат без какого-либо сообщения об ошибке.

Чаще всего NULL возникает в трёх ситуациях. Первая — левое соединение: если для записи основной таблицы нет пары в присоединяемой, все поля второй таблицы будут NULL. Вторая — обращение к реквизиту составного типа через точку: например, поле «Регистратор.Номер» даст NULL для тех записей, где тип регистратора не содержит реквизита «Номер». Третья — объединение запросов, где в одной из частей поле отсутствует или имеет несовместимый тип.

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

Базовый способ проверки — оператор «ЕСТЬ NULL» (в английском синтаксисе — IS NULL). Он ставится после имени поля и возвращает истину, если значение отсутствует. Обратная проверка записывается как «НЕ Поле ЕСТЬ NULL» — так отбираются только заполненные значения.

ВЫБРАТЬ

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

Остатки.КоличествоОстаток КАК Остаток

ИЗ

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

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

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

ГДЕ

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

Этот запрос вернёт все товары, по которым вообще нет записей в таблице остатков. Обратите внимание: если заменить условие на «Остатки.КоличествоОстаток = 0», результат будет другим — вы получите товары с нулевым остатком, но не те, по которым движений не было вовсе. Различие принципиально для отчётов по складу и товарам без движения.

Проверка в конструкции ВЫБОР

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

ВЫБРАТЬ

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

ВЫБОР

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

ТОГДА "Нет движений"

ИНАЧЕ "Есть остаток"

КОНЕЦ КАК Статус

ИЗ

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

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

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

Замена NULL функцией ЕСТЬNULL

Функция ЕСТЬNULL(Выражение, ЗначениеЗамены) возвращает первый аргумент, если он не NULL, и второй аргумент — если NULL. Это стандартный приём для числовых полей в отчётах: вместо отсутствующего остатка выводится ноль, и итоги считаются корректно.

ВЫБРАТЬ

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

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

ИЗ

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

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

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

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

Какой способ выбрать: ЕСТЬ NULL или ЕСТЬNULL

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

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

Оператор ЕСТЬ NULL

Подходит для фильтрации записей в ГДЕ и для ветвления в ВЫБОР. Не заменяет значение, а только проверяет его.

Функция ЕСТЬNULL

Подходит для подстановки значения по умолчанию в вычисляемых полях и итогах. Не работает как условие фильтрации.

ВЫБОР + ЕСТЬ NULL

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

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

Проверка NULL в коде на встроенном языке

Когда результат запроса обрабатывается в модуле, NULL из выборки проверяется иначе. Во встроенном языке 1С нет прямого аналога оператора ЕСТЬ NULL, поэтому используются два подхода. Первый — сравнение со значением Неопределено не сработает: NULL из запроса не равен Неопределено. Правильный способ — функция ЗначениеЗаполнено() или проверка через ТипЗнч.

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

Если Выборка.Остаток = NULL Тогда

// Так тоже можно: встроенный язык понимает NULL

Продолжить;

КонецЕсли;

КонецЦикла;

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

NULL в СКД и динамических списках

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

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

Порядок действий при отладке
  1. 1
    Выполните запрос в консоли запросов и найдите поля со значением NULL в результате
  2. 2
    Определите источник NULL: левое соединение, составной тип или объединение
  3. 3
    Решите задачу: отфильтровать записи (ЕСТЬ NULL в ГДЕ) или заменить значение (ЕСТЬNULL в полях)
  4. 4
    Проверьте совместимость типов аргументов ЕСТЬNULL
  5. 5
    Выполните запрос повторно и сверьте количество строк и итоги с ожидаемыми

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

Самая распространённая ошибка — сравнение через равенство. Условие «ГДЕ Поле = NULL» синтаксически допустимо, конструктор запросов его не подсветит как ошибку, но результат всегда будет пустым. Аналогично условие «Поле <> NULL» отбракует все записи, включая заполненные. Единственный корректный синтаксис — «Поле ЕСТЬ NULL» и «НЕ Поле ЕСТЬ NULL».

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

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

Типичные ошибки
01
Условие «Поле = NULL» — всегда ложь, запрос возвращает пустой результат без ошибки
02
Фильтр по полю правой таблицы в ГДЕ при левом соединении — строки без пары теряются
03
ЕСТЬNULL с несовместимыми типами аргументов — ошибка выполнения запроса
04
Сравнение NULL из выборки с Неопределено в коде — условие не срабатывает
05
Ожидание, что КОЛИЧЕСТВО(Поле) посчитает NULL-строки — они не учитываются

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

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

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

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

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

Совпадает с количеством до изменения

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

Строк стало меньше — условие попало в ГДЕ

Значения в поле после ЕСТЬNULL
Норма

Вместо NULL отображается значение по умолчанию

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

Поле по-прежнему пустое или ошибка типов

Итоги по числовым полям
Норма

Суммы совпадают с контрольной выборкой

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

Итоги занижены — часть строк потеряна при соединении

Для отладки удобно использовать консоль запросов: она наглядно показывает NULL в результате и позволяет быстро проверить разные варианты условий без перезапуска всей обработки. Также полезно временно вывести в выборку вычисляемое поле-флаг «ВЫБОР КОГДА Поле ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 КОНЕЦ» — по нему легко оценить масштаб проблемы до выбора способа исправления.

Итог

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

NULL проверяется только оператором ЕСТЬ NULL, а заменяется функцией ЕСТЬNULL с совместимым типом второго аргумента. Сравнение через «= NULL» не работает. При левых соединениях следите, чтобы условия по правой таблице не превращали соединение во внутреннее, и обрабатывайте NULL до передачи данных в итоги, СКД и движения документов.

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

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

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

Почему условие «Поле = NULL» не выдаёт ошибку, но ничего не находит?

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

Можно ли использовать ЕСТЬNULL для полей ссылочного типа?

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

Как отобрать записи, где поле заполнено, то есть не NULL?

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

Влияет ли ЕСТЬNULL на производительность запроса?

В подавляющем большинстве случаев влияние незначительно — это простая скалярная функция. Заметные тормоза чаще вызваны не самой ЕСТЬNULL, а тем, что её применяют к полю в условии соединения или фильтрации, из-за чего СУБД не может использовать индекс. По возможности применяйте функцию только в списке выбираемых полей, а условия формулируйте через ЕСТЬ NULL.

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

Так же — оператором ЕСТЬ NULL. Например, «ГДЕ Регистратор.Номер ЕСТЬ NULL» отберёт записи, где тип регистратора не содержит реквизита «Номер». Альтернатива — предварительно отфильтровать записи по типу через условие «Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг», тогда обращение к реквизиту будет безопасным и NULL не возникнет.