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

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

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

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

При разработке запросов в 1С проверка числового значения на ноль — одна из самых частых задач: отобрать документы с нулевой суммой, найти товары без остатка, отфильтровать строки с пустым количеством. При этом разработчики регулярно сталкиваются с тем, что условие ГДЕ Количество = 0 не находит записи, которые визуально выглядят «нулевыми».

Причина почти всегда одна: в результате запроса вместо числа 0 находится значение NULL. Оно появляется при левом соединении таблиц, при обращении к реквизиту через точку от пустой ссылки, при соединении с виртуальными таблицами остатков, где записи просто нет. NULL не равен нулю, не равен пустой строке и не равен даже самому себе — любое сравнение с NULL возвращает не ИСТИНА и не ЛОЖЬ, а неопределённость, и такая строка в выборку не попадает.

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

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

Стандартная ситуация: запрос соединяет номенклатуру с виртуальной таблицей остатков через ЛЕВОЕ СОЕДИНЕНИЕ. Для товаров, по которым движений не было, таблица остатков не содержит записи, и поле КоличествоОстаток получает значение NULL. Условие ГДЕ Остатки.КоличествоОстаток = 0 такие товары не вернёт, хотя фактический остаток у них нулевой.

Это стандартное поведение трёхзначной логики SQL, которое платформа 1С наследует полностью. Сравнение NULL = 0 не даёт ИСТИНУ, поэтому строка отбрасывается. Аналогично условие NULL <> 0 тоже не сработает — разработчик не получит ни «нулевых», ни «ненулевых» строк там, где ожидает увидеть хотя бы одну группу.

Вторая частая причина — разыменование. Выражение вида Документ.Контрагент.ИНН для документа с незаполненным контрагентом вернёт NULL, а не пустую строку. То же касается числовых реквизитов, полученных через точку от пустой ссылки.

Простая проверка на ноль через ГДЕ

Если поле гарантированно не содержит NULL — например, это реквизит табличной части или поле самой таблицы документа — достаточно простого условия:

ВЫБРАТЬ

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

Товары.Количество КАК Количество

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

ГДЕ

Товары.Количество = 0

Такой запрос вернёт строки табличных частей, где количество явно равно нулю. Обратите внимание: незаполненный числовой реквизит в 1С хранится именно как 0, а не как NULL, поэтому для реквизитов самой таблицы простое сравнение работает надёжно.

Для отбора ненулевых значений используется обратное условие Товары.Количество <> 0. Здесь та же логика: условие корректно, пока в поле нет NULL.

Функция ЕСТЬNULL — основной инструмент

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

ВЫБРАТЬ

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

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

ИЗ

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

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

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

ГДЕ

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

Такой запрос корректно вернёт все товары с нулевым остатком — и те, у которых остаток записан как 0, и те, по которым движений не было вовсе. Именно этот вариант чаще всего нужен на практике при поиске «пустых» остатков, задолженности или оборотов.

Второй аргумент ЕСТЬNULL должен совпадать по типу с первым. Для числового поля указывайте 0, для строкового — пустую строку "", для даты — ДАТАВРЕМЯ(1,1,1). Несовпадение типов приведёт к ошибке исполнения запроса или неочевидным результатам при сравнении.

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

Альтернативы: ЕСТЬ NULL и конструкция ВЫБОР

Проверка именно на NULL

Иногда нужно найти не нулевые, а именно отсутствующие значения — например, товары без единственной записи в регистре. Для этого служит оператор ЕСТЬ NULL:

ГДЕ

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

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

Замена нуля на другое значение через ВЫБОР

Когда ноль нужно не отфильтровать, а обработать — например, вывести вместо него текст или подставить значение по умолчанию — используется конструкция ВЫБОР:

ВЫБОР

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

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

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

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

Этот приём удобен в отчётах: пользователь видит понятный статус вместо нуля, а исходное числовое поле можно вывести рядом для сортировки и итогов. Внутри ВЫБОР действуют те же правила работы с NULL, поэтому ЕСТЬNULL в условии КОГДА остаётся обязательным для соединяемых полей.

Способы проверки на ноль

ГДЕ Поле = 0

Подходит для реквизитов самой таблицы, где NULL невозможен. Самый быстрый и читаемый вариант.

ЕСТЬNULL(Поле, 0) = 0

Универсальный вариант для соединений и разыменований. Отбирает и нули, и отсутствующие записи.

Поле ЕСТЬ NULL

Нужен, когда требуется найти именно отсутствие записи, а не нулевое значение.

ВЫБОР ... КОНЕЦ

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

Ноль в параметрах и в итогах

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

Запрос.УстановитьПараметр("Порог", 0);

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

Деление на ноль — ещё один риск в вычисляемых полях. Выражение Сумма / Количество при нулевом количестве вызовет ошибку. Защититесь через ВЫБОР:

ВЫБОР

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

ТОГДА 0

ИНАЧЕ Т.Сумма / Т.Количество

КОНЕЦ КАК СредняяЦена

Типичные ошибки
01
Сравнение Поле = 0 после левого соединения — строки с NULL теряются, отчёт занижает количество записей.
02
Условие Поле <> 0 с целью «убрать нули» — вместе с нулями исчезают и строки с NULL, что искажает выборку.
03
ЕСТЬNULL с несовпадающим типом второго аргумента, например ЕСТЬNULL(ЧисловоеПоле, "") — ошибка исполнения запроса.
04
Деление на поле без проверки на ноль — запрос падает с ошибкой деления на ноль при первой же пустой строке.
05
Ожидание, что СУММА по пустой группе вернёт 0 — на самом деле возвращается NULL, и итоги в отчёте пустеют.

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

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

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

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

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

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

Записи с явным нулём в поле
Норма

Попадают в выборку при условии = 0

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

Не попадают — проверьте тип поля и условие

Записи без строк в соединяемой таблице
Норма

Попадают в выборку при ЕСТЬNULL(Поле, 0) = 0

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

Теряются — в условии нет ЕСТЬNULL

Итоговые суммы по группам
Норма

Пустые группы показывают 0

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

Пустые ячейки — СУММА не обёрнута в ЕСТЬNULL

Вычисляемые поля с делением
Норма

Запрос выполняется на любых данных

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

Ошибка деления на ноль — нет проверки через ВЫБОР

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

Чем NULL отличается от 0 в запросе 1С?

0 — это конкретное числовое значение, которое участвует в сравнениях и арифметике. NULL означает отсутствие данных: любое сравнение с ним не даёт ИСТИНЫ, поэтому строки с NULL отфильтровываются условиями = 0 и <> 0 одинаково. Для обработки NULL используют ЕСТЬNULL или оператор ЕСТЬ NULL.

Почему условие ГДЕ Остаток = 0 не находит товары без остатка?

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

Как проверить строковое поле на пустоту?

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

Как избежать ошибки деления на ноль в запросе?

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

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

Агрегатная функция СУММА по группе, где все значения равны NULL, возвращает NULL. Чтобы в итогах отображался ноль, оберните агрегат: ЕСТЬNULL(СУММА(Поле), 0). Это особенно важно в отчётах на СКД, где пустые итоги выглядят как ошибка расчёта.

Можно ли вместо ЕСТЬNULL использовать ВЫБОР для проверки на ноль?

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

Итог

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

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