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

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

ВЫБОР КОГДА ТОГДА в запросах 1С: синтаксис и практические примеры

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

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

Классическая ситуация: в отчёте нужно вывести текстовый статус документа («Проведён», «На проверке», «Отклонён»), хотя в базе хранится числовой или ссылочный признак. Другой пример — расчёт цены с разными коэффициентами в зависимости от категории клиента. В обоих случаях логика решается одной конструкцией ВЫБОР прямо в тексте запроса.

Ниже разобран синтаксис, типовые сценарии, ограничения по типам данных, вложенные условия, отличия от конструкции ЕСТЬNULL и типичные ошибки, из-за которых запрос либо не выполняется, либо возвращает неожиданный результат.

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

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

ВЫБОР

КОГДА <Условие1> ТОГДА <Значение1>

КОГДА <Условие2> ТОГДА <Значение2>

ИНАЧЕ <ЗначениеПоУмолчанию>

КОНЕЦ

Условия проверяются последовательно сверху вниз. Как только одно из условий оказывается истинным, возвращается соответствующее значение, а остальные ветви не вычисляются. Если ни одно условие не выполнилось, возвращается значение из ветви ИНАЧЕ. Если ветвь ИНАЧЕ отсутствует и ни одно условие не сработало — результатом будет NULL.

Конструкцию можно использовать в списке выбираемых полей, в условиях ГДЕ, в предложении ИМЕЮЩИЕ, в итогах и даже в параметрах виртуальных таблиц там, где это допустимо синтаксисом. Чаще всего она применяется как вычисляемое поле выборки с псевдонимом:

ВЫБРАТЬ

Документ.Номер,

ВЫБОР

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

КОГДА Документ.ПометкаУдаления ТОГДА "Помечен на удаление"

ИНАЧЕ "Записан"

КОНЕЦ КАК Статус

ИЗ

Документ.РеализацияТоваровУслуг КАК Документ

Базовый пример: статус документа текстом

Самая частая задача — преобразовать технические признаки в понятные пользователю значения. Возьмём заказы покупателей и выведем состояние каждого документа:

ВЫБРАТЬ

Заказ.Номер КАК Номер,

Заказ.Дата КАК Дата,

ВЫБОР

КОГДА Заказ.ПометкаУдаления ТОГДА "Помечен на удаление"

КОГДА НЕ Заказ.Проведен ТОГДА "Черновик"

КОГДА Заказ.СуммаДокумента > 100000 ТОГДА "Крупный заказ"

ИНАЧЕ "Обычный заказ"

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

ИЗ

Документ.ЗаказПокупателя КАК Заказ

Обратите внимание на порядок условий. Проверка пометки удаления стоит первой, потому что помеченный документ может быть одновременно и проведённым — и тогда важнее показать именно пометку. Если поменять условия местами, помеченный проведённый документ попадёт в ветку «Крупный заказ» или «Обычный заказ», что исказит картину.

Правило простое: более специфичные и приоритетные условия размещайте выше, общие — ниже. Ветвь ИНАЧЕ здесь играет роль «всё остальное» и гарантирует, что поле Состояние никогда не будет пустым.

Расчёт значений по условию: скидки, НДС, категории

Вторая типовая задача — вычисляемые числовые поля. Например, расчёт процента скидки в зависимости от суммы продажи:

ВЫБРАТЬ

Продажи.Номенклатура КАК Товар,

Продажи.СуммаОборот КАК Сумма,

Продажи.СуммаОборот * ВЫБОР

КОГДА Продажи.СуммаОборот >= 500000 ТОГДА 0.10

КОГДА Продажи.СуммаОборот >= 100000 ТОГДА 0.05

ИНАЧЕ 0

КОНЕЦ КАК СуммаСкидки

ИЗ

РегистрНакопления.Продажи.Обороты КАК Продажи

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

В условиях допустимо использовать сравнения, И, ИЛИ, НЕ, проверку В ИЕРАРХИИ, В списке значений, а также функции языка запросов — например, ПОДСТРОКА или РАЗНОСТЬДАТ. Это позволяет строить довольно сложную логику без выхода во встроенный язык.

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

Требования к типам данных и работа с NULL

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

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

Чтобы поведение было предсказуемым, оборачивайте потенциально пустые поля в ЕСТЬNULL:

ВЫБОР

КОГДА ЕСТЬNULL(Остатки.КоличествоОстаток, 0) > 0 ТОГДА "В наличии"

ИНАЧЕ "Нет на складе"

КОНЕЦ КАК НаличиеТовара

Вложенные конструкции и альтернативы

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

Для простых случаев существуют более короткие альтернативы, которые стоит знать, чтобы не раздувать запрос:

ЗадачаИнструментКогда применять
Заменить NULL на значениеЕСТЬNULL(Поле, Значение)Два варианта: есть значение или NULL
Несколько условий, разные результатыВЫБОР КОГДА ТОГДАТри и более ветвей, сложные условия
Фильтрация строк по условиюГДЕ / ИМЕЮЩИЕНужно отобрать строки, а не вычислить значение
Выбор по равенству одному полюВЫБОР с условиями Поле = ЗначениеПеречисление фиксированных вариантов

ЕСТЬNULL не заменяет ВЫБОР, но часто используется вместе с ним. Обратная ситуация — использование ВЫБОР там, где достаточно ЕСТЬNULL — встречается часто и лишь усложняет текст запроса без выигрыша.

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

ВЫБОР КОГДА ТОГДА

Подходит для трёх и более ветвей и сложных условий с И/ИЛИ. Ограничение — все ветви должны возвращать совместимые типы.

ЕСТЬNULL

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

Вычисляемые поля СКД

Подходят, когда логика нужна только в отчёте. Минус — переносит вычисление на этап формирования отчёта и усложняет переиспользование.

ВЫБОР в итогах, группировках и СКД

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

ВЫБРАТЬ

Продажи.Менеджер КАК Менеджер,

СУММА(ВЫБОР

КОГДА Продажи.Период >= &НачалоТекущегоКвартала

ТОГДА Продажи.СуммаОборот

ИНАЧЕ 0

КОНЕЦ) КАК СуммаТекущийКвартал,

СУММА(Продажи.СуммаОборот) КАК СуммаВсего

ИЗ

РегистрНакопления.Продажи.Обороты КАК Продажи

СГРУППИРОВАТЬ ПО

Продажи.Менеджер

Такой приём позволяет в одном запросе получить несколько показателей по разным условиям — например, суммы по текущему и прошлому периодам рядом в одной строке. Это заметно эффективнее, чем два отдельных запроса с последующим соединением.

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

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

Типичные ошибки и как их проверить

Первая ошибка — отсутствие ветви ИНАЧЕ. Формально она необязательна, но без неё несработавшие условия дают NULL, который потом «теряется» в итогах: суммы по группам не сходятся с общим итогом, а строки с пустым полем выпадают из отборов.

Вторая ошибка — неверный порядок условий. Например, условие Сумма > 100000 перед условием Сумма > 500000 сделает вторую ветвь недостижимой: любая сумма больше 500000 уже удовлетворяет первому условию. Проверяйте граничные значения: ровно 100000, ровно 500000, ноль.

Третья ошибка — сравнение строк с учётом длины и пробелов. Строковые значения в условиях чувствительны к точному совпадению, и лишний пробел в литерале приведёт к тому, что ветвь никогда не сработает. Для строкового сравнения по шаблону используйте ПОДОБНО.

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

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

Количество строк со значением из ИНАЧЕ
Норма

Доля строк соответствует ожиданиям по данным

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

Почти все строки попали в ИНАЧЕ — вероятно, NULL в условиях или ошибка в сравнении

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

Во всех строках одинаковый тип значения

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

Запрос не выполняется с ошибкой несовместимости типов

Граничные значения условий
Норма

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

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

Пороговые значения уходят не в ту ветвь — проверьте знаки &gt; и &gt;=

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

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

Да, конструкция допустима в предложении ГДЕ, например: ГДЕ ВЫБОР КОГДА &ТолькоПроведённые ТОГДА Документ.Проведен ИНАЧЕ ИСТИНА КОНЕЦ. Однако для фильтрации по параметру часто достаточно конструкции с ИЛИ: ГДЕ (НЕ &ТолькоПроведённые ИЛИ Документ.Проведен), которая читается проще.

Чем ВЫБОР отличается от ЕСТЬNULL?

ЕСТЬNULL решает единственную задачу — подставить значение вместо NULL. ВЫБОР проверяет произвольные условий и возвращает разные значения по ветвям. Если нужно только заменить NULL, используйте ЕСТЬNULL — она короче; для логики с несколькими условиями нужен ВЫБОР.

Есть ли ограничение на количество ветвей КОГДА?

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

Почему запрос с ВЫБОР выдаёт ошибку о несовместимости типов?

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

Работает ли ВЫБОР в виртуальных таблицах регистров?

В списке полей выборки из виртуальной таблицы — да, конструкция применяется к полученным полям как обычно. А вот в параметрах самой виртуальной таблицы (условия отбора) использование ВЫБОР ограничено — туда лучше передавать уже вычисленные параметры.

Как отладить сложную конструкцию ВЫБОР?

Откройте запрос в консоли запросов и временно выведите каждое условие отдельным полем с результатом ИСТИНА/ЛОЖЬ. Так видно, какая ветвь срабатывает для конкретных строк, и легко найти условие, которое ведёт себя не так, как ожидалось.

Итог

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

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