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

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

ВЫБОР КОГДА ТОГДА ИНАЧЕ в запросе 1С: как работает и как применять

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

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

Конструкция работает во всех современных версиях платформы 1С:Предприятие 8 и одинаково доступна в обычных запросах, в СКД, в динамических списках и в произвольных выражениях СКД. Синтаксис практически совпадает с SQL-оператором CASE, поэтому разработчикам, знакомым с SQL, освоить её несложно.

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

Синтаксис конструкции ВЫБОР в запросе 1С

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

ВЫБОР

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

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

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

КОНЕЦ

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

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

Простой пример: статус документа текстом

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

ВЫБРАТЬ

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

Реализация.Дата,

ВЫБОР

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

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

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

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

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

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

ИЗ

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

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

После КОНЕЦ через ключевое слово КАК задаётся имя поля — без псевдонима обращаться к результату в выборке будет неудобно, а в СКД поле вообще не появится в списке доступных.

Условия с диапазонами и вычислениями

В условиях КОГДА допустимы сравнения, логические операции И/ИЛИ/НЕ, проверка В ИЕРАРХИИ и В списке. Это позволяет строить градации, например размер скидки по сумме документа:

ВЫБОР

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

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

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

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

ИНАЧЕ 0

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

Здесь тоже критичен порядок: более «сильное» условие (больший порог) идёт первым. Значения в ТОГДА могут быть не только константами, но и выражениями — полями таблицы, арифметическими операциями, результатами встроенных функций языка запросов.

Ещё один практический сценарий — замена пустой ссылки читаемым текстом:

ВЫБОР

КОГДА Товары.Склад = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка)

ТОГДА "Склад не указан"

ИНАЧЕ Товары.Склад.Наименование

КОНЕЦ КАК Склад

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

ВЫБОР или ЕСТЬNULL: что выбрать

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

// Длинно

ВЫБОР

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

ТОГДА 0

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

КОНЕЦ

// Коротко и эквивалентно

ЕСТЬNULL(Остатки.Количество, 0)

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

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

ВЫБОР КОГДА ТОГДА ИНАЧЕ

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

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

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

Обработка в коде после запроса

Сложная логика, которую трудно выразить в запросе. Минус: медленнее и больше кода.

Требование совместимости типов

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

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

ВЫБОР в секциях ИМЕЮЩИЕ, УПОРЯДОЧИТЬ ПО и в СКД

Конструкция допустима не только в списке выбора. Её можно использовать в ИМЕЮЩИЕ для фильтрации сгруппированных данных, в УПОРЯДОЧИТЬ ПО для нестандартной сортировки и даже в условии ГДЕ. Пример сортировки, где срочные документы выводятся первыми:

УПОРЯДОЧИТЬ ПО

ВЫБОР

КОГДА Заказы.Срочный ТОГДА 1

ИНАЧЕ 2

КОНЕЦ,

Заказы.Дата

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

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

Типичные ошибки и как их найти

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

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

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

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

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

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

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

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

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

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

Есть пустые ячейки или значения из чужой ветки

Граничные случаи: NULL, пустые ссылки, нули
Норма

Обработаны веткой ИНАЧЕ или отдельным КОГДА

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

Возвращается NULL, хотя в данных такого условия не предполагалось

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

Сопоставимо с версией запроса без ВЫБОР

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

Запрос стал выполняться заметно дольше — проверьте, не попал ли ВЫБОР в соединение

Итог

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

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

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

Можно ли использовать ВЫБОР без ИНАЧЕ?

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

Сколько условий КОГДА можно написать в одном ВЫБОРе?

Жёсткого ограничения платформа не накладывает — условий может быть сколько угодно. Однако конструкция с десятками веток трудно читается и сопровождается. Если веток больше пяти-семи, стоит подумать о соединении со справочником соответствий или о переносе логики в вычисляемое поле СКД.

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

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

Можно ли вернуть в разных ветках значения разных типов?

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

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

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

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

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