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

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

NULL в запросах 1С: как проверить поле через ЕСТЬ NULL и ЕСТЬNULL

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

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

Главная ловушка в том, что NULL нельзя сравнивать обычным знаком равенства: условие ГДЕ Поле = NULL никогда не сработает, потому что любое сравнение с NULL даёт не ИСТИНА и не ЛОЖЬ, а неопределённый результат, который отбрасывается. Поэтому для проверки используется специальный синтаксис Поле ЕСТЬ NULL или Поле ЕСТЬ НЕ 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) КАК Остаток

ИЗ

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

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

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

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

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

Как найти записи без связанных данных
  1. 1
    Составьте запрос с ЛЕВЫМ СОЕДИНЕНИЕМ основной таблицы к проверяемой
  2. 2
    В секции ГДЕ добавьте условие: ПолеСвязи ЕСТЬ NULL
  3. 3
    Убедитесь, что проверяете поле именно из правой (присоединяемой) таблицы
  4. 4
    Выполните запрос в консоли запросов и проверьте, что в выборку попали только записи без пары
  5. 5
    Если нужен список с заменой — используйте ЕСТЬNULL в списке полей вместо отбора

Типовые сценарии использования

Поиск документов без движений

Задача: найти документы, по которым нет записей в регистре. Левое соединение таблицы документов с регистром и условие ГДЕ Регистр.Регистратор ЕСТЬ NULL отберёт именно «пустые» документы. Это стандартный способ поиска потерянных или непроведённых объектов при диагностике данных.

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

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

Проверка незаполненных полей после соединения

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

ЕСТЬ NULL или ЕСТЬNULL

ЕСТЬ NULL в ГДЕ

Отбор строк: оставить только записи, где значение отсутствует (или наоборот, присутствует). Не меняет сами данные в выборке.

ЕСТЬNULL в списке полей

Замена NULL на значение по умолчанию (0, пустая строка, пустая ссылка). Все строки сохраняются, NULL исчезает из результата.

Комбинация обоих

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

NULL в соединениях, группировках и вычислениях

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

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

В условиях соединения (секция ПО) NULL тоже не совпадает ни с чем, включая другой NULL. Поэтому соединение по полю, которое может содержать NULL, никогда не склеит такие строки между собой.

Типичные ошибки при работе с NULL
01
Условие «Поле = NULL» вместо «Поле ЕСТЬ NULL» — запрос молча возвращает пустоту
02
Сложение полей из разных таблиц без ЕСТЬNULL — итоговая сумма становится NULL
03
Проверка «Поле = &ПустаяСсылка» вместо ЕСТЬ NULL — пустая ссылка и NULL не одно и то же
04
ЕСТЬNULL с несовместимыми типами аргументов — ошибка выполнения запроса
05
Ожидание, что соединение по NULL-полям склеит строки — NULL никогда не равен NULL в условии ПО

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

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

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

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

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

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

В выборке присутствуют, NULL заменён на 0 или пустую ссылку

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

Строки пропали или в колонке стоит NULL

Суммы и вычисления
Норма

Числовые поля заполнены во всех строках

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

Итог по строке NULL, хотя часть слагаемых есть

Отбор по ЕСТЬ NULL
Норма

Попали только записи без связанных данных

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

Пустой результат при заведомо существующих «сиротах» — проверьте, не используется ли «= NULL»

Часто задаваемые вопросы

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

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

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

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

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

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

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

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

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

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

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

Выберите СУММА(ВЫБОР КОГДА Поле ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) — такой подсчёт явно покажет число NULL-строк. Вариант КОЛИЧЕСТВО(Поле) посчитает наоборот — только строки, где значение есть.

Итог

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

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