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