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

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

ВЫБОР КОГДА ИСТИНА в запросах 1С: как работает условная логика

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

Конструкция ВЫБОР КОГДА ИСТИНА — это аналог оператора CASE в языке запросов 1С. Она позволяет вернуть разные значения в одном поле выборки в зависимости от условий, не прибегая к соединениям нескольких запросов и не вынося логику в код после выполнения запроса. Это один из самых востребованных приёмов при построении отчётов, динамических списков и СКД.

Механика проста: система последовательно проверяет условия после каждого КОГДА и возвращает значение из первой ветки, где условие оказалось истинным. Если ни одно условие не сработало, возвращается значение из ИНАЧЕ, а при его отсутствии — NULL. Понимание порядка проверки веток критично: пересекающиеся условия могут дать не тот результат, который ожидал разработчик.

Материал разбирает синтаксис, практические сценарии (статусы документов, признаки, расчётные поля), ограничения по типам данных, типичные ошибки и способы проверить результат до выкладки в рабочую базу.

Синтаксис конструкции ВЫБОР КОГДА

Полная форма конструкции выглядит так:

ВЫБОР

КОГДА Заказ.Сумма > 100000

ТОГДА "Крупный"

КОГДА Заказ.Сумма > 10000

ТОГДА "Средний"

ИНАЧЕ "Мелкий"

КОНЕЦ КАК КатегорияЗаказа

Ключевые элементы: ВЫБОР открывает конструкцию, каждая пара КОГДА–ТОГДА задаёт условие и возвращаемое значение, ИНАЧЕ — значение по умолчанию, КОНЕЦ завершает блок. После КОНЕЦ обычно ставят псевдоним через КАК, чтобы к полю можно было обращаться в СКД или коде.

Существует и сокращённая форма — ВЫБОР с выражением после ключевого слова: ВЫБОР Товары.Статус КОГДА 1 ТОГДА "Новый" КОГДА 2 ТОГДА "В работе" КОНЕЦ. Она сравнивает выражение на равенство с каждым вариантом. Но в практике чаще используется полная форма, потому что она поддерживает любые условия: сравнения, И, ИЛИ, НЕ, подзапросы, проверки на NULL.

Порядок проверки условий и типичная ловушка

Условия проверяются строго сверху вниз. Как только одно из них истинно, остальные ветки игнорируются. Если условия пересекаются, побеждает та ветка, что стоит выше, — даже если логически вы имели в виду другое.

Классическая ошибка — поставить общее условие раньше частного. В примере выше Сумма > 10000 охватывает и суммы больше 100 000, поэтому ветка «Крупный» обязана идти первой. Поменяйте ветки местами — и все заказы свыше 10 000 попадут в «Средний», а категория «Крупный» останется пустой без каких-либо сообщений об ошибке.

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

Практические сценарии использования

Вычисляемый статус документа

Частая задача — показать в списке или отчёте понятный статус, которого нет в явном реквизите. Например, по признакам проведения и пометки удаления:

ВЫБОР

КОГДА РеализацияТоваров.ПометкаУдаления

ТОГДА "Помечен на удаление"

КОГДА РеализацияТоваров.Проведен

ТОГДА "Проведен"

ИНАЧЕ "Черновик"

КОНЕЦ КАК Состояние

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

Замена NULL на читаемое значение

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

ВЫБОР

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

ТОГДА 0

ИНАЧЕ Остатки.КоличествоОстаток

КОНЕЦ КАК Остаток

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

Приведение нескольких значений к одному признаку

ВЫБОР удобен для свёртки справочных значений в группы: «наша организация / контрагент», «налоговая / неналоговая операция». Вместо соединения с дополнительной таблицей соответствий перечислите варианты через ИЛИ в одной ветке КОГДА.

Если веток больше пяти-семи и они описывают соответствие одних ссылок другим, перенесите соответствие в регистр сведений и используйте левое соединение. Длинные ВЫБОР трудно поддерживать, а изменение логики потребует правки кода вместо данных.
ПЗ
Практическое замечание

Ограничения по типам данных

Все ветки ТОГДА и ИНАЧЕ должны возвращать значения совместимых типов. Если одна ветка возвращает строку, а другая — число, поле получит составной тип. В запросе это пройдёт незаметно, но дальше начнутся проблемы: в СКД некорректно сработают отборы и сортировка, в коде сравнение Если Строка.Поле = 0 даст неожиданный результат для строковых значений.

Особый случай — строки разной длины. Если в одной ветке строка из 10 символов, а в другой — из 100, итоговый тип может быть усечён до минимальной длины в некоторых сценариях использования. Надёжный приём — явно привести значение через ВЫРАЗИТЬ:

ВЫРАЗИТЬ(ВЫБОР

КОГДА Док.Проведен ТОГДА "Проведен"

ИНАЧЕ "Не проведен"

КОНЕЦ КАК СТРОКА(50)) КАК Состояние

ВЫБОР в СКД и динамических списках

В схеме компоновки данных конструкция ВЫБОР работает как в обычном запросе, но есть нюанс: если вычисляемое поле участвует в отборах или группировках, убедитесь, что ветка ИНАЧЕ задана — иначе строки с NULL сформируют отдельную «пустую» группу, которая смутит пользователя отчёта.

Для динамических списков учтите, что произвольный запрос с ВЫБОР может отключить стандартные механизмы: например, если поле с ВЫБОР сделать ключевым или использовать в основной таблице некорректно, пропадёт динамическое обновление. Вычисляемые поля в динамических списках должны опираться на данные основной таблицы или её соединений, а ключевое поле оставайтесь ссылкой на запись.

Альтернативы конструкции ВЫБОР

Не каждая задача требует ВЫБОР. Для подстановки значения вместо NULL короче и читабельнее функция ЕСТЬNULL. Для соответствия «ссылка → значение» на большом количестве вариантов лучше подходит левое соединение с регистром сведений или таблицей значений, помещённой во временную таблицу. Для агрегатной логики («сумма только по проведённым») используйте ВЫБОР внутри агрегатной функции: СУММА(ВЫБОР КОГДА Проведен ТОГДА Сумма ИНАЧЕ 0 КОНЕЦ) — это стандартный приём условного суммирования.

Сравнение вариантов

ВЫБОР КОГДА

Универсальные условия любой сложности; ограничение — все ветки должны давать совместимые типы

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

Только замена NULL на конкретное значение; короче, но не умеет ветвлений

Соединение с таблицей соответствий

Много однотипных соответствий ссылка-значение; требует поддержки данных в регистре или временной таблице

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

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

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

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

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

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

Все строки имеют осмысленные значения из заданного набора

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

Есть NULL или неожиданные значения — проверьте ИНАЧЕ и ЕСТЬ NULL

Граничные значения
Норма

Значение ровно на пороге попадает в ожидаемую категорию

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

Пороговые строки в соседней категории — проверьте знаки > и >=

Все категории
Норма

Каждая ветка представлена хотя бы в тестовых данных

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

Категория пуста — вероятно, её перекрывает более общее условие выше

Порядок действий
  1. 1
    Сформулируйте все категории результата и выпишите условие для каждой
  2. 2
    Упорядочьте условия от частных к общим
  3. 3
    Напишите конструкцию ВЫБОР с обязательной веткой ИНАЧЕ
  4. 4
    Приведите результат к нужному типу через ВЫРАЗИТЬ при необходимости
  5. 5
    Выполните запрос в консоли и проверьте результат на граничных значениях
  6. 6
    Сгруппируйте по вычисляемому полю и сверьте распределение строк

Часто задаваемые вопросы

Можно ли использовать ВЫБОР в секции ГДЕ?

Технически да, но делать так не стоит: фильтрация по вычисляемому выражению не использует индексы и приводит к полному сканированию таблицы. Перепишите условие напрямую через исходные реквизиты с И/ИЛИ — это и быстрее, и понятнее.

Почему условие Поле = NULL никогда не срабатывает?

В логике запросов любое сравнение с NULL даёт неопределённый результат, а не ИСТИНУ. Для проверки на NULL используйте оператор ЕСТЬ NULL: КОГДА Поле ЕСТЬ NULL ТОГДА ... — только так ветка сработает корректно.

Что вернёт ВЫБОР, если ни одно условие не выполнилось и ИНАЧЕ нет?

Вернётся NULL. Это частая причина «пустых» групп в отчётах СКД и неожиданных значений в коде. Всегда добавляйте ИНАЧЕ с осмысленным значением по умолчанию, даже если уверены, что условия покрывают все случаи.

Можно ли вкладывать один ВЫБОР в другой?

Да, вложенность допустима: в ветке ТОГДА или ИНАЧЕ можно разместить ещё одну конструкцию ВЫБОР. Однако глубже двух уровней код становится трудно читаемым — в таких случаях лучше разбить логику на несколько полей запроса или перенести часть условий во временную таблицу.

Работает ли ВЫБОР с перечислениями и предопределёнными значениями?

Да, ссылку на значение перечисления указывают через ЗНАЧЕНИЕ(Перечисление.ИмяПеречисления.ИмяЗначения). Это стандартный способ сравнить поле с конкретным значением перечисления прямо в условии КОГДА без параметров запроса.

Чем ВЫБОР отличается от вычисляемого поля СКД?

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

Итог

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

ВЫБОР КОГДА возвращает значение первой истинной ветки, поэтому частные условия ставьте выше общих. Всегда добавляйте ИНАЧЕ, следите за совместимостью типов веток и проверяйте NULL через ЕСТЬ NULL. Не используйте ВЫБОР для фильтрации в ГДЕ — только для представления и агрегации данных.