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

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

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

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

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

Типичная задача выглядит так: нужно вывести статус заказа словами, рассчитать скидку в зависимости от суммы, подставить признак «Просрочено» по дате оплаты или привести значения из разных источников к единому виду. Всё это решается одним выражением ВЫБОР внутри секции ВЫБРАТЬ.

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

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

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

ВЫБОР

КОГДА <Условие1> ТОГДА <Выражение1>

КОГДА <Условие2> ТОГДА <Выражение2>

ИНАЧЕ <ВыражениеПоУмолчанию>

КОНЕЦ

Условия проверяются сверху вниз. Как только одно из них оказалось истинным, возвращается соответствующее выражение, а остальные ветки не вычисляются. Это важно: порядок условий влияет на результат, поэтому более частные условия ставят выше более общих.

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

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

Простой пример: вычислить статус по условию

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

ВЫБРАТЬ

Реализация.Номер,

Реализация.СуммаДокумента,

ВЫБОР

КОГДА Реализация.Оплачен

ТОГДА "Оплачен"

ИНАЧЕ "Не оплачен"

КОНЕЦ КАК СтатусОплаты

ИЗ

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

Здесь поле СтатусОплаты вычисляется на стороне СУБД и сразу приходит в результат запроса готовой строкой. Псевдоним КАК СтатусОплаты обязателен, если вы планируете обращаться к полю по имени при обходе выборки или использовать его в СКД.

Условий КОГДА может быть сколько угодно. Например, градация по сумме:

ВЫБОР

КОГДА Сумма >= 100000 ТОГДА "Крупный"

КОГДА Сумма >= 10000 ТОГДА "Средний"

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

КОНЕЦ КАК КатегорияКлиента

Обратите внимание: проверка идёт от большего порога к меньшему. Если поменять условия местами, заказ на 150000 попадёт в ветку «Средний», потому что условие >= 10000 сработает раньше и дальнейшая проверка прекратится.

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

Простая форма ВЫБОР с выражением сравнения

Существует сокращённая форма, когда все условия сравнивают одно и то же выражение с разными значениями:

ВЫБОР Документ.ВидОперации

КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа)

ТОГДА "Реализация"

КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Возврат)

ТОГДА "Возврат поставщику"

ИНАЧЕ "Прочее"

КОНЕЦ

Эта форма компактнее и читается легче, но работает только на равенство. Если нужны сравнения «больше», «меньше», проверки на NULL или составные условия с И/ИЛИ — используйте полную поисковую форму.

Практическое применение сокращённой формы — сопоставление перечислений, буквенных кодов и числовых кодов состояний их текстовым представлениям. Для всего остального полная форма универсальнее.

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

Полная форма (КОГДА условие)

Поддерживает любые условия: диапазоны, NULL, И/ИЛИ. Подходит для большинства задач, но записи длиннее.

Сокращённая форма (ВЫБОР выражение)

Только сравнение на равенство. Удобна для перечислений и кодов, компактнее, но менее гибкая.

Вычисление в коде после запроса

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

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

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

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

Защититься можно двумя способами: обернуть поле в ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) внутри условия или добавить отдельную ветку КОГДА Поле ЕСТЬ NULL ТОГДА ... перед остальными условиями. Первый вариант короче, второй нагляднее, когда NULL — осмысленное отдельное состояние.

ВЫБОР в условиях, итогах и СКД

Конструкция работает не только в списке полей. В секции ГДЕ она позволяет строить гибкие фильтры, например отбор по разным полям в зависимости от параметра:

ГДЕ

ВЫБОР

КОГДА &ТолькоПросроченные

ТОГДА Заказ.ДатаОплаты < &ТекущаяДата

ИНАЧЕ ИСТИНА

КОНЕЦ

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

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

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

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

Вторая ошибка — несовместимые типы в ветках. Например, ТОГДА 0 в одной ветке и ТОГДА "" в другой. Запрос может выполниться, но тип поля станет составным, и дальнейшие сравнения этого поля начнут вести себя неожиданно.

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

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

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

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

Каждая тестовая строка попала в ожидаемую ветку

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

Пустые значения или всё в ИНАЧЕ

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

Одиночный тип (строка, число, дата)

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

Составной тип из-за разных типов в ветках

Строки из левых соединений
Норма

NULL обработан через ЕСТЬNULL или отдельную ветку

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

Строки без связи дают неожиданные значения

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

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

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

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

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

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

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

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

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

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

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

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

Чаще всего сравниваются значения разных типов: поле типа «дата» со строкой или с датой, полученной не тем способом. Передавайте дату через параметр запроса (&Дата) или используйте ДАТАВРЕМЯ(год, месяц, день). Также проверьте, что в поле нет NULL — сравнение с NULL никогда не даёт ИСТИНУ.

Как в ветке ТОГДА вернуть пустую ссылку?

Через ЗНАЧЕНИЕ с указанием типа, например: ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка). Важно, чтобы тип пустой ссылки совпадал с типом значений в других ветках, иначе получите составной тип поля.

Работает ли ВЫБОР в динамических списках форм?

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

Чем ВЫБОР отличается от функции ?() во встроенном языке?

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

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

Да, конструкция допустима в ИМЕЮЩИЕ, обычно внутри агрегатной функции — например, отобрать группы, где сумма по условию превышает порог: ИМЕЮЩИЕ СУММА(ВЫБОР КОГДА ... ТОГДА Сумма ИНАЧЕ 0 КОНЕЦ) > &Порог. Это стандартный приём для фильтрации сгруппированных данных.