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