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