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

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

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

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

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

Важно понимать: в 1С существует несколько разных «пустых» значений, и путать их нельзя. NULL — это значение из мира запросов и базы данных. Неопределено — значение встроенного языка, означающее отсутствие значения у переменной или параметра. Пустая ссылка — это ссылка, указывающая «ни на что», но имеющая конкретный тип. Каждое из них проверяется своим способом, и универсальной функции «проверить на пустоту» не существует.

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

Чем 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()» в языке нет. Операция «Значение = NULL» возвращает Истина только когда значение действительно NULL. При этом арифметические операции с NULL дают NULL, а сравнения NULL с другими значениями в запросах всегда дают ложь — это нужно учитывать при построении условий.

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

Проверка на Неопределено

Неопределено проверяется прямым сравнением: «Если Параметр = Неопределено Тогда». Это стандартный способ проверить, передан ли необязательный параметр в процедуру или функцию, нашёл ли метод искомый объект:

НайденныйДокумент = Документы.РеализацияТоваровУслуг.НайтиПоНомеру(НомерДок, ДатаДок);

Если НайденныйДокумент = Неопределено Тогда

ВызватьИсключение "Документ с номером " + НомерДок + " не найден";

КонецЕсли;

Также сравнение с Неопределено применяется при работе с соответствиями и структурами: обращение к несуществующему ключу соответствия возвращает Неопределено, а метод Свойство() структуры позволяет проверить наличие ключа без обращения к нему. Для структур безопаснее использовать именно Свойство("Ключ", НайденноеЗначение) — метод вернёт Ложь, если ключа нет, и запишет значение во второй параметр, если ключ есть.

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

Проверка пустых ссылок и незаполненных значений

Пустая ссылка проверяется методом Пустая() или сравнением со значением, полученным через метод ПустаяСсылка() менеджера объекта:

Если Документ.Контрагент.Пустая() Тогда

Сообщить("Не заполнен контрагент");

КонецЕсли;

// Альтернатива:

Если Документ.Контрагент = Справочники.Контрагенты.ПустаяСсылка() Тогда

...

КонецЕсли;

В запросах пустая ссылка проверяется сравнением со значением «ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)». Это принципиально отличается от ЕСТЬ NULL: незаполненный реквизит ссылочного типа хранит пустую ссылку, а не NULL, поэтому условие ЕСТЬ NULL его не поймает.

Для универсальной проверки «заполнено ли значение» существует функция ЗначениеЗаполнено(). Она возвращает Ложь для Неопределено, NULL, пустых ссылок, пустых строк, нулевых чисел, пустых дат и пустых коллекций. Это удобно для валидации реквизитов формы, но в тонкой логике лучше использовать точечные проверки: ЗначениеЗаполнено не различает, чем именно значение «пустое», а число 0 и пустая строка она считает незаполненными, что не всегда соответствует бизнес-логике.

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

ЕСТЬ NULL в запросе

Подходит для отбора записей с отсутствующими данными прямо в запросе. Не работает для пустых ссылок и Неопределено.

ЕСТЬNULL(Поле, Значение)

Заменяет NULL на заданное значение на этапе запроса. Оптимально для полей, участвующих в расчётах. Требует совместимости типов.

Сравнение = NULL в коде

Проверка полей выборки при обходе результата запроса. Нужна, если NULL не обработан в тексте запроса.

= Неопределено

Проверка результатов функций, параметров, ключей соответствий. Не применима к NULL из запросов.

ЗначениеЗаполнено()

Универсальная проверка для валидации реквизитов. Не различает вид пустоты и считает 0 незаполненным.

NULL в соединениях и агрегатных функциях

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

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

Агрегатная функция СУММА по пустой группировке возвращает NULL, а не 0. Функция КОЛИЧЕСТВО в той же ситуации возвращает 0. Если отчёт группирует данные и часть групп может оказаться пустой, оборачивайте суммы в ЕСТЬNULL, иначе в итоговых строках появятся пустые ячейки, а выражения в СКД с такими полями дадут ошибку или пустоту.

Порядок действий
  1. 1
    Определите источник значения: поле запроса, результат функции или реквизит объекта
  2. 2
    Для поля из левого соединения или агрегатной функции — оберните его в ЕСТЬNULL в тексте запроса
  3. 3
    Для отбора записей без данных — добавьте условие «Поле ЕСТЬ NULL» в секцию ГДЕ
  4. 4
    При обходе выборки в коде — проверяйте «Если Выборка.Поле = NULL Тогда»
  5. 5
    Для результата функции или параметра — сравнивайте с Неопределено
  6. 6
    Для ссылочного реквизита — проверяйте методом Пустая()
  7. 7
    Запустите код на данных, где искомые связи гарантированно отсутствуют, и убедитесь, что ветка обработки NULL срабатывает

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

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

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

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

Итог

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

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

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

Чем отличается NULL от Неопределено в 1С?

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

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

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

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

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

Почему СУММА возвращает пустое значение вместо нуля?

Агрегатная функция СУММА по пустому набору записей возвращает NULL, а не 0 — это корректное поведение платформы. Чтобы получить ноль, оберните вызов: «ЕСТЬNULL(СУММА(Таблица.Сумма), 0)». Функция КОЛИЧЕСТВО в аналогичной ситуации возвращает 0 и обработки не требует.

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

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

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

Да, функция ЗначениеЗаполнено возвращает Ложь и для NULL, и для Неопределено, и для пустых ссылок. Но она также считает незаполненными ноль, пустую строку и пустую дату, поэтому для расчётной логики, где ноль — допустимое значение, лучше использовать точечное сравнение с NULL.