Разработка и Конфигурация · 12 мин
1С запрос: ВЫБОР КОГДА NULL — как проверить и заменить пустые значения
Как в запросе 1С проверить и заменить NULL: конструкция ВЫБОР КОГДА NULL, функция ЕСТЬNULL, типичные ошибки с левым соединением и примеры кода.
Значение NULL в запросах 1С появляется всякий раз, когда соединение таблиц не нашло соответствующей записи: например, при левом соединении справочника с регистром остатков для товара без движений поля остатка будут равны NULL. Если такое значение попадёт в сравнение, арифметику или группировку без обработки, результат запроса окажется неожиданным: строки «потеряются», суммы не посчитаются, условия не сработают.
Стандартный способ обработки — конструкция ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ в сочетании с проверкой ЕСТЬ NULL, а также более короткая функция ЕСТЬNULL(). Обе конструкции работают во всех современных версиях платформы 1С:Предприятие 8.3 и поддерживаются консолью запросов, СКД и динамическими списками.
Ниже разобраны практические сценарии: как выглядит NULL в результате запроса, как заменить его нулём или строкой, как проверять NULL в условии ГДЕ, какие ошибки допускают разработчики чаще всего и как убедиться, что запрос обрабатывает пустые значения корректно.
Что такое NULL в языке запросов 1С и откуда он берётся
NULL — это специальное значение, означающее «данных нет», а не пустую строку, не ноль и не пустую ссылку. Это принципиально: выражение NULL = 0 ложно, NULL = "" ложно и даже NULL = NULL не является истиной в логике сравнения. Любая арифметическая операция с NULL (сложение, умножение) тоже возвращает NULL.
Чаще всего NULL возникает при соединении таблиц. Классический пример — левое соединение справочника «Номенклатура» с виртуальной таблицей остатков: для товара, по которому нет записей в регистре, поля количества и суммы будут NULL. Также NULL появляется при различии типов в объединении, при обращении к реквизиту составного типа, не заполненному для конкретной строки, и при получении данных через точку от NULL-ссылки.
Проверка на NULL через ВЫБОР КОГДА
Универсальная конструкция выглядит так: ВЫБОР КОГДА Поле ЕСТЬ NULL ТОГДА ЗначениеПоУмолчанию ИНАЧЕ Поле КОНЕЦ. Она позволяет не только заменить NULL, но и реализовать разветвлённую логику — например, вывести текстовый признак «нет остатка» вместо числа.
ВЫБРАТЬ
Товары.Ссылка КАК Номенклатура,
ВЫБОР
КОГДА Остатки.КоличествоОстаток ЕСТЬ NULL
ТОГДА 0
ИНАЧЕ Остатки.КоличествоОстаток
КОНЕЦ КАК Остаток
ИЗ
Справочник.Номенклатура КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Товары.Ссылка = Остатки.НоменклатураКонструкцию ВЫБОР КОГДА удобно применять, когда веток больше двух: например, NULL заменить нулём, отрицательный остаток пометить отдельным признаком, а положительный вывести как есть. Ветки КОГДА проверяются сверху вниз, срабатывает первая истинная, поэтому проверку на NULL обычно ставят первой.
Обратите внимание: в ветках ТОГДА и ИНАЧЕ желательно возвращать значения совместимых типов. Если в одной ветке число, а в другой строка, тип поля результата станет составным, что может осложнить дальнейшую обработку в СКД или при выгрузке в таблицу значений.
Функция ЕСТЬNULL — короткая замена NULL
Когда задача сводится к простой замене NULL на конкретное значение, вместо громоздкого ВЫБОР КОГДА используют функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). Она читается легче и уменьшает объём текста запроса, особенно когда таких полей несколько.
ВЫБРАТЬ
Товары.Ссылка КАК Номенклатура,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток,
ЕСТЬNULL(Цены.Цена, 0) КАК Цена
ИЗ
Справочник.Номенклатура КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Товары.Ссылка = Остатки.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
ПО Товары.Ссылка = Цены.НоменклатураВажное ограничение: оба аргумента ЕСТЬNULL должны иметь совместимые типы. Заменить числовой остаток строкой «нет данных» через ЕСТЬNULL не получится — для этого как раз нужен ВЫБОР КОГДА с приведением типа, например ВЫРАЗИТЬ(Остаток КАК СТРОКА(20)).
ВЫБОР КОГДА или ЕСТЬNULL
Подходит для простой замены NULL одним значением того же типа. Короче и читаемее, но не поддерживает разные типы и множественные условия.
Подходит для сложной логики: несколько веток, разные типы результата, дополнительные условия помимо NULL. Текст длиннее, но гибкость выше.
Проверка NULL в условии ГДЕ и соединениях
Отфильтровать строки, где поле не заполнено из-за отсутствия связанной записи, можно условием ГДЕ Поле ЕСТЬ NULL. Обратный вариант — ГДЕ Поле ЕСТЬ НЕ NULL — оставляет только строки с найденным соответствием, что фактически превращает левое соединение во внутреннее по эффекту.
Типичная ошибка — писать ГДЕ Поле = NULL или ГДЕ Поле = &Параметр, где параметр равен NULL. Такое сравнение никогда не выполнится, и запрос вернёт пустой результат без какой-либо ошибки. Если параметр может содержать NULL, условие строят так: ГДЕ (Поле = &Параметр ИЛИ &Параметр ЕСТЬ NULL И Поле ЕСТЬ NULL) либо передают вместо NULL значение Неопределено и обрабатывают его отдельно.
Отдельный случай — условие в самом соединении. Если добавить фильтр по правой таблице в секцию ГДЕ, левое соединение превратится во внутреннее и строки без остатков пропадут. Правильное место для такого фильтра — условие ПО внутри соединения: тогда отбор применяется до соединения, а строки левой таблицы сохраняются с NULL в полях правой.
NULL в группировках, итогах и агрегатных функциях
Агрегатные функции СУММА, СРЕДНЕЕ, МАКСИМУМ и МИНИМУМ игнорируют NULL-значения, но если все значения в группе равны NULL, результатом СУММА будет NULL, а не ноль. Поэтому замену NULL лучше выполнять до группировки — обернуть поле в ЕСТЬNULL уже на уровне детальных записей или вложенного запроса.
При группировке по полю, которое может быть NULL, все NULL-строки попадут в одну группу с пустым значением группировочного поля. В отчётах на СКД такая группа выглядит как строка без наименования и часто сбивает пользователей. Решение — заменить NULL осмысленным признаком через ВЫБОР КОГДА ещё в запросе набора данных.
При расчёте итогов по иерархии NULL в группировочном поле может также привести к тому, что строка не попадёт ни в один узел дерева. Проверяйте итоговую сумму по отчёту: если сумма по группам не сходится с общим итогом, одна из вероятных причин — «потерянные» NULL-строки.
Типичные ошибки при работе с NULL
Первая и самая частая ошибка — сравнение через равенство: Поле = NULL. Запрос выполнится без сообщения об ошибке, но вернёт пустой результат, и причину бывает трудно найти. Второе место занимает арифметика без обработки: выражение Цена * Остаток даст NULL для всех товаров без остатков, и итоговая сумма по документу окажется заниженной или NULL.
Третья группа ошибок связана с обращением через точку: Остатки.Номенклатура.Артикул, когда Номенклатура равна NULL, тоже вернёт NULL, и это нормально, но если дальше это поле сравнивается или группируется, эффект накапливается. Наконец, в СКД разработчики иногда забывают, что вычисляемые поля и ресурсы тоже получают NULL из запроса, и удивляются пустым ячейкам в отчёте.
Как проверить результат запроса
Отладку удобно вести в консоли запросов: выполните запрос, найдите строки, где ожидаемое числовое поле пусто, и убедитесь, что после добавления ЕСТЬNULL там появился ноль. Контрольный приём — временно вывести само исходное поле рядом с обработанным и сравнить: где исходное NULL, обработанное должно содержать значение по умолчанию.
Для проверки корректности соединения полезно посчитать строки до и после: количество записей левой таблицы не должно уменьшаться после левого соединения. Если уменьшилось — ищите фильтр по правой таблице в секции ГДЕ или неверное условие соединения.
Как проверить результат
Равно числу записей левой таблицы с учётом заданных отборов
Строк меньше — вероятно, условие ГДЕ отсекло NULL-строки соединения
Показывает 0 или заданное значение по умолчанию
Пусто (NULL) — замена через ЕСТЬNULL не выполнена
Совпадает с суммой по детальным строкам
Итог меньше или NULL — в арифметике участвуют необработанные NULL
Все строки попадают в именованные группы
Есть группа без наименования — группировочное поле содержит NULL
Порядок безопасного внедрения изменений
Изменения в запросах, которые используются в отчётах и проведении документов, лучше сначала проверять на копии базы или в консоли запросов: ошибка в обработке NULL не вызывает исключения, а молча искажает данные, и заметить это в рабочей базе можно слишком поздно — например, при сверке остатков.
- 1Найдите в запросе все поля из правых таблиц левых соединений и поля, получаемые через точку от необязательных ссылок.
- 2Определите для каждого поля значение по умолчанию: 0 для чисел, пустая строка или осмысленный признак для строк.
- 3Замените простые случаи на ЕСТЬNULL(Поле, Значение), сложную логику оформите через ВЫБОР КОГДА Поле ЕСТЬ NULL.
- 4Проверьте условия ГДЕ: замените сравнения с NULL на ЕСТЬ NULL, фильтры по правым таблицам перенесите в условие соединения.
- 5Выполните запрос в консоли на тестовых данных, сверьте количество строк и итоговые суммы до и после изменения.
- 6Только после совпадения контрольных цифр переносите изменения в рабочий код или макет СКД.
Что важно запомнить
NULL — это отсутствие значения, а не ноль и не пустая строка. Проверяйте его только через ЕСТЬ NULL, заменяйте через ЕСТЬNULL или ВЫБОР КОГДА, фильтры по правым таблицам держите в условии соединения, а корректность результата подтверждайте сверкой количества строк и итогов.
Частые вопросы
Чем NULL отличается от Неопределено в 1С?
NULL — значение языка запросов, означающее отсутствие данных в поле результата. Неопределено — значение встроенного языка 1С, используемое в коде модулей. В запрос напрямую передать Неопределено нельзя: параметр со значением Неопределено либо вызовет ошибку, либо потребует явной обработки, поэтому в коде его обычно заменяют конкретным значением до выполнения запроса.
Почему условие «ГДЕ Поле = NULL» не работает?
По правилам логики NULL не равен ничему, включая сам себя, поэтому сравнение через «=» всегда даёт ложь. Запрос при этом выполняется без ошибки и просто ничего не возвращает. Правильная форма записи — ГДЕ Поле ЕСТЬ NULL или ГДЕ Поле ЕСТЬ НЕ NULL для обратного отбора.
Что выбрать: ЕСТЬNULL или ВЫБОР КОГДА?
Если нужно просто заменить NULL одним значением того же типа — используйте ЕСТЬNULL, запрос будет короче. Если требуется несколько условий, разные типы результата или дополнительная логика (например, отдельная обработка отрицательных значений) — применяйте ВЫБОР КОГДА ... КОНЕЦ.
Почему после добавления условия в запрос пропали товары без остатков?
Вы добавили фильтр по полю правой таблицы в секцию ГДЕ. Для строк, где соединение не нашло остатков, это поле равно NULL, условие не выполняется, и строка исключается. Перенесите условие в секцию ПО левого соединения либо дополните его конструкцией ИЛИ Поле ЕСТЬ NULL.
Как заменить NULL на строку «нет данных» в числовом поле?
Напрямую через ЕСТЬNULL это невозможно из-за несовместимости типов. Используйте ВЫБОР КОГДА с приведением: в ветке ИНАЧЕ преобразуйте число через ВЫРАЗИТЬ(Поле КАК СТРОКА(20)), а в ветке ТОГДА верните нужный текст. Учтите, что по такому полю уже нельзя будет считать суммы и строить числовые итоги.
Влияет ли ЕСТЬNULL на производительность запроса?
Сама функция практически бесплатна — это простая проверка на уровне СУБД. На производительность гораздо сильнее влияет структура соединений и отсутствие индексов по полям связи. Заметные тормоза после «добавления ЕСТЬNULL» обычно означают, что одновременно изменили порядок соединений или условия отбора, а не саму функцию.