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

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

Оператор КОГДА в языке запросов 1С: синтаксис и практика

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

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

Типовые задачи, где без КОГДА не обойтись: расшифровка числового статуса документа в читаемое название, подмена NULL пользовательским значением, разделение сумм по признаку (приход/расход, свои/чужие), формирование признаков для группировок и итогов. Всё это выполняется на стороне СУБД, что быстрее, чем обход выборки в цикле на встроенном языке.

Ниже разобраны обе формы оператора — простая и поисковая, типичные ошибки с типами и NULL, влияние на производительность и ситуации, когда КОГДА стоит заменить другим инструментом.

Синтаксис: две формы оператора ВЫБОР КОГДА

Простая форма сравнивает одно выражение с набором значений. Она компактна, когда проверяется равенство одного поля нескольким константам:

ВЫБОР &Статус

КОГДА 1 ТОГДА "Новый"

КОГДА 2 ТОГДА "В работе"

КОГДА 3 ТОГДА "Завершён"

ИНАЧЕ "Неизвестно"

КОНЕЦ

Поисковая форма проверяет произвольные логические условия, включая сравнения разных полей, диапазоны и вложенные функции:

ВЫБОР

КОГДА Продажи.Сумма >= 100000 ТОГДА "Крупная"

КОГДА Продажи.Сумма >= 10000 ТОГДА "Средняя"

ИНАЧЕ "Мелкая"

КОНЕЦ КАК КатегорияСделки

Условия проверяются сверху вниз, и срабатывает первое истинное. Поэтому порядок веток важен: если условие «больше 10000» поставить выше «больше 100000», крупные сделки никогда не попадут в свою категорию. Ветка ИНАЧЕ формально необязательна, но без неё при несовпадении всех условий поле получит значение NULL, что часто ломает дальнейшую логику отчёта.

Типовые сценарии применения

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

ВЫБОР

КОГДА Заказы.Проведен ТОГДА "Проведён"

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

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

Второй частый сценарий — условное суммирование в группировках. Вместо двух отдельных запросов по приходу и расходу пишут один:

СУММА(ВЫБОР

КОГДА Остатки.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)

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

ИНАЧЕ 0

КОНЕЦ) КАК Приход

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

ВЫБОР

КОГДА Цены.Цена ЕСТЬ NULL ТОГДА 0

ИНАЧЕ Цены.Цена

КОНЕЦ КАК Цена

Впрочем, для простой подстановки вместо NULL короче использовать функцию ЕСТЬNULL(Цены.Цена, 0) — она читается легче и делает то же самое.

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

ВЫБОР КОГДА

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

ЕСТЬNULL(поле, значение)

Короткая замена NULL на значение по умолчанию. Не умеет проверять другие условия.

Соединение со справочником

Правильный путь, когда расшифровок много и они хранятся в данных (например, статусы в перечислении). КОГДА с десятками веток хуже читается и сложнее поддерживается.

КОГДА в секции УСЛОВИЕ и в параметрах виртуальных таблиц

Конструкция ВЫБОР работает не только в списке полей выборки. Её можно применять в секции ГДЕ, в условиях соединения, в итогах и даже в параметрах виртуальных таблиц регистров — там, где платформа разрешает произвольные выражения.

Пример фильтрации по вычисляемому признаку:

ГДЕ

ВЫБОР

КОГДА Док.Сумма > 0 ТОГДА ИСТИНА

ИНАЧЕ ЛОЖЬ

КОНЕЦ

На практике такой фильтр лучше переписать прямым условием Док.Сумма > 0 — результат тот же, а план запроса проще. ВЫБОР в секции ГДЕ оправдан, когда условие нельзя выразить одним сравнением, например проверка попадания даты в один из нескольких периодов с разными действиями.

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

Типы данных результата и частые ошибки

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

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

Третья ошибка — забытая ветка ИНАЧЕ. Если ни одно условие не сработало, поле получит NULL, а дальше это значение попадёт в группировку, сравнение или вычисление итогов. В отчётах это проявляется как «пустая» строка в группировке или пропавшие суммы.

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

Производительность: когда КОГДА замедляет запрос

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

Правило простое: в условиях КОГДА используйте поля уже выбранных таблиц, константы и параметры. Если нужны данные из другой таблицы — соедините её в секции ИЗ заранее, а в КОГДА ссылайтесь на её поля. Это позволяет СУБД построить нормальный план с соединением вместо повторных обращений.

Также не стоит строить гигантские цепочки из сотен веток для расшифровки значений, которые уже есть в базе. Если соответствие «код — название» хранится в справочнике или перечислении, соединение с ним и надёжнее, и понятнее, и не требует правки запроса при добавлении нового значения.

Пошаговая проверка запроса с КОГДА

Перед тем как отправлять запрос с конструкцией ВЫБОР в рабочий код, полезно пройти короткий цикл проверки в консоли запросов. Это занимает несколько минут и отсекает большинство ошибок до отладки отчёта целиком.

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

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

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

Все строки заполнены значениями из веток ТОГДА/ИНАЧЕ

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

Есть NULL или пустые значения — не хватает ИНАЧЕ или условие не срабатывает

Тип поля в результате
Норма

Один тип во всех строках

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

Смешение типов — несогласованные ветки

Время выполнения
Норма

Сопоставимо с аналогичным запросом без ВЫБОР

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

Кратный рост времени — в условиях вложенные запросы или лишние соединения

Альтернативы и границы применения

КОГДА — не единственный способ условной логики в запросах. Для подстановки вместо NULL короче ЕСТЬNULL. Для расшифровки перечислений правильнее соединение или обращение к представлению через механизмы отчёта. Для сложной бизнес-логики, зависящей от множества таблиц, честнее вынести вычисление в код на встроенном языке и передать результат в запрос параметром или временной таблицей.

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

Маршрут решения

Как выбрать действие

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

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

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

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

Можно ли использовать КОГДА без ВЫБОР, как в Excel?

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

Чем ВЫБОР КОГДА отличается от функции ЕСТЬNULL?

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

Почему условие КОГДА Поле = NULL не срабатывает?

Потому что NULL в трёхзначной логике SQL не равен ничему, включая NULL. Любое сравнение с NULL даёт «неизвестно», и ветка не выполняется. Корректная проверка — КОГДА Поле ЕСТЬ NULL ТОГДА ...

Сколько веток КОГДА допустимо в одной конструкции?

Жёсткого ограничения платформа не накладывает, но практический предел определяется читаемостью. До десятка веток — нормально; когда веток десятки, запрос стоит пересмотреть: скорее всего, соответствие значений нужно хранить в данных и получать соединением.

Работает ли ВЫБОР КОГДА в СКД и динамических списках?

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

Влияет ли ВЫБОР КОГДА на скорость запроса?

Само по себе ветвление вычисляется быстро. Замедление возникает, если внутри условий есть вложенные запросы или обращения к таблицам, не включённым в соединения. Проверяйте время выполнения на реальном объёме данных и выносите нужные поля в секцию ИЗ через соединение.