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