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

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

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

Как использовать оператор ВЫБОР КОГДА (аналог CASE) в запросах 1С: синтаксис, примеры с несколькими условиями, типичные ошибки и проверка результата.

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

Такой подход незаменим, когда нужно вывести текстовый статус вместо числового кода, подставить признак по нескольким условиям, заменить NULL или сгруппировать данные по вычисляемому признаку. Запрос с ВЫБОР выполняется на стороне СУБД, поэтому обычно работает быстрее, чем перебор выборки в цикле с условиями «Если…Тогда».

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

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

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

ВЫБОР

КОГДА <условие 1> ТОГДА <значение 1>

КОГДА <условие 2> ТОГДА <значение 2>

ИНАЧЕ <значение по умолчанию>

КОНЕЦ

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

Ветка ИНАЧЕ формально необязательна. Если её опустить и ни одно условие не сработало, поле получит значение NULL. На практике это частая причина неожиданных пустых колонок и ошибок при последующем сравнении, поэтому ИНАЧЕ рекомендуется писать всегда — даже если это просто пустая строка или ноль.

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

Типовая задача — вывести в отчёт человекочитаемый статус вместо служебного признака. Например, по виду документа или булеву полю:

ВЫБРАТЬ

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

ВЫБОР

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

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

ИНАЧЕ "Черновик"

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

ИЗ

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

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

Псевдоним КАК Статус обязателен, если поле используется в коде, СКД или динамическом списке: без него обращаться к колонке по имени будет невозможно.

Несколько условий, диапазоны и составные проверки

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

ВЫБОР

КОГДА Долги.СуммаОстаток ЕСТЬ NULL ТОГДА "Нет данных"

КОГДА Долги.СуммаОстаток <= 0 ТОГДА "Переплата"

КОГДА Долги.СуммаОстаток < 10000 ТОГДА "Незначительный долг"

ИНАЧЕ "Крупный долг"

КОНЕЦ КАК КатегорияДолга

Здесь важны два момента. Первый: проверка на NULL стоит первой, потому что сравнение NULL с числом не даст ИСТИНА — такая строка «провалится» до ветки ИНАЧЕ. Второй: границы диапазонов не должны пересекаться неоднозначно — условие «< 10000» после «<= 0» корректно, потому что нулевые и отрицательные суммы уже отсечены выше.

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

ВЫБОР в секциях ГДЕ, СГРУППИРОВАТЬ ПО и итогах

Конструкция ВЫБОР работает не только в списке полей ВЫБРАТЬ. Её можно применять в условии ГДЕ, чтобы отфильтровать строки по вычисляемому признаку, и в группировке, чтобы собрать итоги по категориям:

ВЫБРАТЬ

ВЫБОР

КОГДА Продажи.СуммаОборот >= 100000 ТОГДА "Крупные"

ИНАЧЕ "Обычные"

КОНЕЦ КАК Категория,

СУММА(Продажи.СуммаОборот) КАК Сумма

ИЗ

РегистрНакопления.Продажи.Обороты КАК Продажи

СГРУППИРОВАТЬ ПО

ВЫБОР

КОГДА Продажи.СуммаОборот >= 100000 ТОГДА "Крупные"

ИНАЧЕ "Обычные"

КОНЕЦ

Обратите внимание: выражение ВЫБОР в группировке дублируется полностью, ссылаться на псевдоним из списка полей в СГРУППИРОВАТЬ ПО нельзя. Это увеличивает текст запроса, но является ограничением языка. Чтобы не разводить дубли, сложную классификацию иногда выносят во временную таблицу, а затем группируют уже по готовому полю.

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

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

Типичные ошибки при использовании КОГДА

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

Типичные ошибки
01
Смешение типов: в одной ветке строка, в другой — число или ссылка. Итог — ошибка выполнения или пустые значения при выгрузке в таблицу значений
02
Отсутствие ИНАЧЕ: при несработавших условиях поле получает NULL, что ломает последующие сравнения и итоги
03
Неверный порядок условий: общее условие стоит выше частного, и частное никогда не срабатывает
04
Сравнение с NULL через знак равенства вместо ЕСТЬ NULL — условие никогда не будет истинным
05
Разная длина строк: если в одной ветке литерал из 10 символов, а в другой из 50, при выгрузке возможно усечение — задавайте тип явно через ВЫРАЗИТЬ

Отдельно стоит ситуация со строками неограниченной длины и ссылочными типами. Если ветки возвращают ссылки на разные виды документов, поле станет составного типа — это допустимо, но усложнит дальнейшую обработку. Если нужна строго одна ссылка, приведите значения через ВЫРАЗИТЬ(... КАК Документ.НужныйВид).

Проверка результата перед переносом в конфигурацию

Прежде чем вставлять запрос в модуль или СКД, выполните его в консоли запросов на реальных данных и проверьте характерные точки. Особое внимание — границам диапазонов и «неудобным» значениям: NULL, ноль, пустая строка, пустая ссылка.

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

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

Строки на границах диапазонов (например, сумма ровно 10000)
Норма

Каждая строка попадает в ожидаемую категорию

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

Граничное значение попало не в ту ветку — проверьте порядок условий и знаки сравнения

Строки с NULL в исходном поле
Норма

NULL обработан отдельной веткой или ИНАЧЕ

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

Поле результата пустое там, где ожидалось значение

Тип колонки результата
Норма

Все значения одного типа, выгрузка в таблицу значений без ошибок

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

Ошибка несовместимости типов или усечённые строки

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

Альтернативы оператору ВЫБОР

Не каждую задачу стоит решать через ВЫБОР. Если значений много и они хранятся в данных (например, соответствие категорий контрагентам), правильнее завести дополнительный реквизит или регистр сведений и соединить таблицы — это проще сопровождать, чем править длинные цепочки КОГДА в десятке запросов.

Для подмены NULL в конкретном поле короче и читабельнее функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). ВЫБОР оправдан там, где условий два и больше либо логика нетривиальна.

Чем заменить ВЫБОР в разных ситуациях

ЕСТЬNULL

Подходит только для подмены NULL одним значением. Короче и быстрее читается, но не умеет условия

Соединение со справочником или регистром сведений

Правильный выбор, когда соответствий много и они меняются пользователями, а не разработчиком

Вычисляемое поле в СКД

Удобно, если логика нужна только в одном отчёте и не должна попадать в текст запроса

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

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

Частые вопросы об операторе ВЫБОР в запросе 1С

Можно ли использовать ВЫБОР внутри агрегатной функции?

Да, например СУММА(ВЫБОР КОГДА Вид = "Продажа" ТОГДА Сумма ИНАЧЕ 0 КОНЕЦ). Это стандартный приём для разнесения одной суммы по нескольким колонкам отчёта. Следите, чтобы ветка ИНАЧЕ возвращала 0, а не NULL — иначе итог по группе может оказаться пустым.

Есть ли ограничение на количество веток КОГДА?

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

Как в ветке ТОГДА вернуть значение перечисления?

Через литерал ЗНАЧЕНИЕ: ТОГДА ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20). Тогда другие ветки должны возвращать значения того же перечисления либо пустую ссылку на него, чтобы тип поля остался единым.

Почему ВЫБОР возвращает пустое значение, хотя условие верное?

Чаще всего условие на самом деле не выполняется: сравнение с NULL через «=», различие типов параметра и поля или лишние пробелы в строке. Проверьте исходное значение отдельным полем в том же запросе и добавьте ветку с ЕСТЬ NULL.

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

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

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

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

Итог

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

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