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

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

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

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

В языке запросов 1С сравнение с NULL работает не так, как привычное сравнение с пустой строкой или пустой ссылкой. Конструкция ГДЕ Поле = NULL всегда вернёт ложь, потому что NULL в 1С — это отсутствие значения, а не конкретное значение. Для проверки используется специальный оператор ЕСТЬ NULL (в английском синтаксисе — IS NULL), а для замены NULL на конкретное значение — функция ЕСТЬNULL().

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

Материал рассчитан на разработчиков и внедренцев, которые пишут запросы в конфигураторе, консоли запросов или коде модулей. Разберём синтаксис проверки, типичные источники NULL, отличие от пустых ссылок и готовые приёмы для отчётов и отборов.

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

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

Основные источники NULL в запросах:

  • Левое соединение (ЛЕВОЕ СОЕДИНЕНИЕ) — если в правой таблице не нашлось подходящей строки, все её поля в результате будут NULL. Это самая частая причина.
  • Обращение через точку к реквизиту объекта, которого нет — например, Документ.Контрагент.ИНН, когда Контрагент не заполнен, даст NULL.
  • Составной тип поля — если реквизит может хранить разные типы, обращение к реквизиту конкретного типа для строки с другим типом вернёт NULL.
  • Различие таблиц в объединении (ОБЪЕДИНИТЬ) — поля, отсутствующие в одной из частей объединения.
  • Регистры с неполным составом измерений при соединении виртуальных таблиц.

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

Оператор ЕСТЬ NULL: синтаксис и примеры

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

Пример: найти документы поступления, для которых не найден договор контрагента:

ВЫБРАТЬ

Поступление.Ссылка КАК Документ,

Договоры.Ссылка КАК Договор

ИЗ

Документ.ПоступлениеТоваровУслуг КАК Поступление

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ДоговорыКонтрагентов КАК Договоры

ПО Поступление.Договор = Договоры.Ссылка

ГДЕ

Договоры.Ссылка ЕСТЬ NULL

Обратный пример — выбрать только те строки, где соединение нашло пару:

ВЫБРАТЬ

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

Цены.Цена КАК Цена

ИЗ

РегистрСведений.ЦеныНоменклатуры КАК Цены

ГДЕ

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

Оператор ЕСТЬ NULL можно комбинировать с другими условиями через И и ИЛИ, но следите за приоритетом: условие ГДЕ А ЕСТЬ NULL ИЛИ Б = 1 и ГДЕ (А ЕСТЬ NULL) ИЛИ (Б = 1) эквивалентны, однако при смешивании И и ИЛИ расставляйте скобки явно.

Функция ЕСТЬNULL: замена NULL на рабочее значение

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

ВЫБРАТЬ

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

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

ИЗ

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

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

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

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

ВЫБОР

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

ТОГДА "нет на складе"

ИНАЧЕ "в наличии"

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

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

bsl
ВЫБРАТЬ
	Товары.Номенклатура,
	ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
ИЗ
	Справочник.Номенклатура КАК Товары
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
		ПО Товары.Ссылка = Остатки.Номенклатура
ГДЕ
	НЕ Остатки.КоличествоОстаток ЕСТЬ NULL

NULL против пустой ссылки и пустой строки: в чём разница

Частая путаница — смешение NULL с «пустыми» значениями. В 1С это три разных состояния:

СостояниеКак возникаетКак проверить
NULLЛевое соединение без пары, обращение к несуществующему реквизитуПоле ЕСТЬ NULL
Пустая ссылкаРеквизит ссылочного типа не заполнен в объектеПоле = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
Пустая строка / нольСтроковый или числовой реквизит не заполненПоле = "" или Поле = 0

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

ГДЕ

Документ.Договор = ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)

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

Чем проверять «нет значения»

ЕСТЬ NULL

Только для NULL из соединений и обращений через точку. Не ловит незаполненные реквизиты объектов.

Сравнение с пустой ссылкой

Для незаполненных ссылочных реквизитов. Требует указания конкретного типа справочника или документа.

ЕСТЬNULL + сравнение

Универсальный вариант: сначала заменить NULL на пустую ссылку, затем сравнить. Покрывает оба случая ценой более громоздкого текста.

Типичные сценарии: где проверка на NULL реально нужна

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

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

Отчёты с нулевыми остатками

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

Составные типы и обращение через точку

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

Параметры отбора в СКД и динамических списках

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

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

Типичные ошибки и как их избежать

Самая распространённая ошибка — написать ГДЕ Поле = NULL и получить пустой результат без какого-либо сообщения об ошибке. Запрос синтаксически корректен, платформа не предупредит. Если запрос «внезапно» ничего не возвращает, первым делом проверьте, нет ли сравнения с NULL через равно.

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

Третья ошибка — использование NULL-полей в арифметике. Выражение Цена * Количество, где один из множителей NULL, даст NULL, и итог по группе может оказаться пустым. Оборачивайте сомнительные операнды в ЕСТЬNULL с нулём.

Четвёртая ошибка — ожидание, что НЕ Поле ЕСТЬ NULL отфильтрует и пустые ссылки. Как показано выше, это разные состояния; для полной проверки «поле заполнено и осмысленно» нужны оба условия.

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

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

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

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

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

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

Сумма строк с NULL и без NULL
Норма

Равна количеству строк запроса без условия

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

Сумма меньше — в соединении дублируются ключи связи

Поле, обёрнутое в ЕСТЬNULL
Норма

В результате нет пустых ячеек, видны значения по умолчанию

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

Пустые ячейки остались — обёрнуто не то поле

Условие по правой таблице
Норма

Условие стоит в секции ПО соединения

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

Условие в ГДЕ — левое соединение стало внутренним

Ещё один практический приём: при отладке запроса с соединениями временно выведите оба поля связи (из левой и правой таблицы) в результат. По NULL в поле правой таблицы сразу видно, какие строки не нашли пару, и легко проверить корректность условия соединения.

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

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

Почему запрос «ГДЕ Поле = NULL» возвращает пустой результат без ошибки?

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

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

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

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

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

Можно ли соединять таблицы по условию ЕСТЬ NULL?

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

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

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

Как в СКД показать записи, где поле не заполнено?

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

Итог

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

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