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