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