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

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

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

ЕСТЬNULL в запросах 1С — что делает функция, синтаксис, примеры с левым соединением, типичные ошибки и отличия от ЕСТЬ NULL и ВЫБОР.

ЕСТЬNULL — это функция встроенного языка запросов 1С, которая заменяет значение NULL на указанное вами значение. Она принимает два аргумента: проверяемое выражение и значение, которое вернётся, если первый аргумент равен NULL. Если первый аргумент не NULL — функция просто возвращает его.

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

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

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

NULL — это специальное значение «отсутствие данных», а не пустая строка, не ноль и не пустая ссылка. Это принципиально: сравнение NULL с чем-либо через обычное равенство не даёт истины даже при сравнении NULL с NULL. Поэтому проверку пишут через специальный оператор ЕСТЬ NULL (IS NULL), а не через знак равенства.

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

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

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

Синтаксис ЕСТЬNULL и правила типов

Общий вид функции:

ЕСТЬNULL(ПроверяемоеВыражение, ЗначениеЕслиNULL)

Оба аргумента обязательны. Функция работает так: если первый аргумент не NULL — возвращается он, иначе возвращается второй аргумент. Важное ограничение: типы аргументов должны быть совместимы. Если первый аргумент — число, замену тоже лучше задавать числом; если ссылка на справочник — пустой ссылкой того же справочника.

Примеры корректного использования:

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

ЕСТЬNULL(Цены.Цена, 0) КАК Цена

ЕСТЬNULL(Товары.Поставщик, ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)) КАК Поставщик

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

Типовой сценарий: левое соединение с регистром

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

ВЫБРАТЬ

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

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

ЕСТЬNULL(Цены.Цена, 0) КАК Цена

ИЗ

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

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

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

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены

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

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

Как добавить ЕСТЬNULL в свой запрос
  1. 1
    Найдите в запросе левые соединения и поля, которые берутся из присоединяемых таблиц.
  2. 2
    Для каждого такого поля оберните его в ЕСТЬNULL с подходящим значением по умолчанию: 0 для чисел, пустая ссылка для ссылок.
  3. 3
    Проверьте вычисляемые поля: если в выражении участвует поле из соединения, оберните его там же — например, ЕСТЬNULL(Остатки.Количество, 0) * Цены.Цена.
  4. 4
    Выполните запрос в консоли запросов и убедитесь, что пустые значения заменились на заданные.
  5. 5
    Проверьте итоги и группировки — суммы должны считаться по всем строкам, а не «теряться».

ЕСТЬNULL в условиях, группировках и вычислениях

В секции ГДЕ

Фильтр ГДЕ Остатки.Количество = 0 не отберёт строки, где количество равно NULL, — такие записи просто выпадут из результата. Если нужно считать отсутствие остатка нулём, пишите:

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

Это частая причина «пропавших» строк в отчётах: разработчик фильтрует по нулю, а товары без движений по регистру в выборку не попадают, потому что для них условие не выполняется.

В агрегатных функциях и арифметике

Любая арифметическая операция с NULL даёт NULL: NULL + 5 — это NULL, а не 5. Поэтому в выражениях вроде Остатки.Количество * Цены.Цена оба операнда стоит защитить через ЕСТЬNULL, иначе часть строк даст пустой результат стоимости. Агрегатная СУММА игнорирует NULL-значения, но если все значения в группе NULL — итог тоже будет NULL, что снова требует обработки.

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

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

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

Отличия от ЕСТЬ NULL, ВЫБОР и ЕСТЬNULL во встроенном языке

Три похожие конструкции решают разные задачи, и их часто путают:

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

Пример с ВЫБОР, где ЕСТЬNULL не подходит из-за несовпадения типов:

ВЫБОР

КОГДА Цены.Цена ЕСТЬ NULL

ТОГДА "Цена не задана"

ИНАЧЕ ВЫРАЗИТЬ(Цены.Цена КАК СТРОКА(15))

КОНЕЦ КАК ЦенаТекстом

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

Что выбрать для обработки NULL

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

Быстрая замена NULL значением того же типа. Оптимально для чисел и ссылок. Не подходит, если замена другого типа или зависит от условия.

Поле ЕСТЬ NULL

Только проверка в условиях ГДЕ и ВЫБОР. Не заменяет значение, а лишь возвращает истину или ложь.

ВЫБОР КОГДА

Универсальный вариант: любые условия и любые типы результата. Минус — более громоздкий синтаксис.

Типичные ошибки и ограничения

Первая и самая массовая ошибка — сравнение с NULL через равенство: ГДЕ Остатки.Количество = NULL. Такое условие не вернёт ни одной строки, потому что NULL не равен ничему, включая сам себя. Запрос выполнится без ошибки, просто результат будет пустым, и причину бывает непросто найти.

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

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

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

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

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

Контрольные признаки корректной работы: строки без данных в присоединяемой таблице присутствуют в результате и содержат заданные значения по умолчанию; суммы по группам совпадают с ручным пересчётом; фильтры по обработанным полям отбирают ожидаемое число записей.

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

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

Строки без связанных записей
Норма

Присутствуют в выборке, в колонках — 0 или заданное значение по умолчанию

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

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

Арифметика с полями соединения
Норма

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

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

Часть строк содержит пустой результат вычисления

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

Итог равен сумме видимых значений

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

Итог меньше ожидаемого — NULL-строки не учтены

Фильтр по нулевому значению
Норма

Отбираются и записи с нулём, и записи без данных

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

В отбор попадают только явные нули

Итог

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

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

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

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

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

Можно ли использовать ЕСТЬNULL в коде модуля, вне запроса?

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

Почему ЕСТЬNULL(Поле, 0) не помогает — в отчёте всё равно пусто?

Чаще всего функция применена не к тому полю или не в том месте: например, обработано поле в списке выборки, но не обработано то же поле внутри арифметического выражения или в ресурсе СКД. Проверьте все места, где участвует поле из левого соединения, включая вычисляемые поля и выражения итогов.

Что выбрать: ЕСТЬNULL или ВЫБОР КОГДА?

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

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

В списке выборки влияние незначительно. Заметное замедление возможно, когда ЕСТЬNULL стоит в условии ГДЕ по полю соединения: оптимизатор может отказаться от использования индекса. На больших таблицах такие условия иногда выгоднее переписать через ОБЪЕДИНИТЬ двух запросов или временную таблицу.

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

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