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