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