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

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

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

Конструкция ВЫБОР КОГДА в языке запросов 1С: синтаксис, примеры с несколькими условиями, КОГДА-ТОГДА-ИНАЧЕ, типичные ошибки и проверка результата в консоли запросов.

Конструкция ВЫБОР КОГДА — аналог оператора CASE в SQL и ЕСЛИ во встроенном языке 1С. Она позволяет прямо в запросе вычислять значение поля в зависимости от условий: подставлять статус документа, группировать суммы по признакам, заменять NULL и пустые ссылки на читаемые значения. Это один из самых востребованных приёмов при написании отчётов и обработок, потому что часть логики переносится из кода на уровень запроса.

Механизм работает так: запрос последовательно проверяет условия после каждого КОГДА и возвращает значение из соответствующего ТОГДА. Если ни одно условие не выполнилось, возвращается значение из ИНАЧЕ, а при отсутствии ИНАЧЕ — NULL. Проверки идут строго сверху вниз, поэтому порядок условий имеет значение: первое совпавшее условие «побеждает», остальные не анализируются.

Конструкция поддерживается во всех современных версиях платформы 1С:Предприятие 8 и работает в консоли запросов, СКД, динамических списках и программно создаваемых запросах. Ниже разобран синтаксис, типовые сценарии, ограничения и ошибки, из-за которых запрос либо не выполняется, либо возвращает неожиданный результат.

Синтаксис конструкции ВЫБОР КОГДА

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

ВЫБОР

КОГДА <Условие1>

ТОГДА <Значение1>

КОГДА <Условие2>

ТОГДА <Значение2>

ИНАЧЕ <ЗначениеПоУмолчанию>

КОНЕЦ

Условий КОГДА может быть сколько угодно. Блок ИНАЧЕ необязателен, но на практике его почти всегда стоит указывать: без него непокрытые условиями строки получат NULL, что часто ломает дальнейшие вычисления, группировки и соединения. Ключевое слово КОНЕЦ обязательно — без него запрос не пройдёт проверку синтаксиса.

Конструкцию можно использовать в секции ВЫБРАТЬ для вычисляемого поля, в условиях ГДЕ и ИМЕЮЩИЕ, в соединениях таблиц и в итогах. Чаще всего её применяют именно в списке выбираемых полей, присваивая результату псевдоним через КАК.

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

Классическая задача — вывести текстовый статус документа вместо булева признака. В запросе к таблице документов это делается одним полем:

ВЫБРАТЬ

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

Реализация.Дата КАК Дата,

ВЫБОР

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

ТОГДА "Проведен"

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

ТОГДА "Помечен на удаление"

ИНАЧЕ "Не проведен"

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

ИЗ

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

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

Результат удобно проверить в консоли запросов: выполните запрос на небольшой выборке и убедитесь, что в колонке «Статус» каждая строка получила ожидаемое значение. Пустые значения в этой колонке означают, что какое-то сочетание признаков не покрыто условиями и ИНАЧЕ отсутствует.

Несколько условий: градация по сумме и диапазонам

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

ВЫБОР

КОГДА Реализация.СуммаДокумента >= 100000

ТОГДА "Крупная"

КОГДА Реализация.СуммаДокумента >= 10000

ТОГДА "Средняя"

ИНАЧЕ "Мелкая"

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

Здесь критично расположение порогов от большего к меньшему. Проверка «>= 100000» должна стоять первой: если поставить «>= 10000» выше, все крупные документы тоже попадут в «Средняя», потому что условие сработает раньше. Это самая частая логическая ошибка при работе с диапазонами.

Условия могут быть составными — с И, ИЛИ и скобками. Например, выделить документы конкретного контрагента за период: КОГДА Реализация.Контрагент = &Контрагент И Реализация.Дата МЕЖДУ &Начало И &Конец ТОГДА .... Параметры передаются в запрос стандартно через УстановитьПараметр.

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

Замена NULL и пустых значений

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

ВЫБОР

КОГДА Остатки.КоличествоОстаток ЕСТЬ NULL

ТОГДА 0

ИНАЧЕ Остатки.КоличествоОстаток

КОНЕЦ КАК Остаток

Для этой задачи есть и более короткая альтернатива — функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). Она делает то же самое в одну строку и читается проще. ВЫБОР КОГДА оправдан, когда замена зависит от дополнительных условий: например, NULL заменяется нулём только для активных номенклатурных позиций, а для архивных — особым значением.

Отдельная ситуация — пустые ссылки. NULL и пустая ссылка в 1С — разные вещи: NULL появляется из соединений, пустая ссылка хранится в самой таблице. Проверка на пустую ссылку делается через ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) или через параметр. Если проверять только ЕСТЬ NULL, строки с пустыми ссылками останутся необработанными.

Чем заменить значение по умолчанию

ВЫБОР КОГДА ЕСТЬ NULL

Гибкий вариант: условие замены можно комбинировать с другими проверками. Подходит для сложной логики, но запись длиннее.

ЕСТЬNULL(Поле, Значение)

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

Представление() и вычисляемые поля СКД

Вариант для отчётов: замена выполняется на уровне настроек отчёта, текст запроса остаётся простым. Не подходит для программных выборок.

ВЫБОР КОГДА в условиях ГДЕ и соединениях

Конструкция работает не только в списке полей. В секции ГДЕ она позволяет фильтровать по вычисляемому признаку, хотя чаще там достаточно обычных логических операторов. Более полезный сценарий — фильтрация по параметру-переключателю:

ГДЕ

ВЫБОР

КОГДА &ТолькоПроведенные

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

ИНАЧЕ ИСТИНА

КОНЕЦ

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

В соединениях ВЫБОР КОГДА используется реже и с осторожностью: условие связи с вычисляемым выражением может заметно замедлить выполнение, потому что СУБД не всегда сможет использовать индексы. Если соединение через ВЫБОР работает медленно, рассмотрите вариант с объединением двух запросов через ОБЪЕДИНИТЬ ВСЕ — часто это быстрее и прозрачнее.

Вложенные конструкции и ограничения

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

Важное ограничение — типы возвращаемых значений. Платформа требует, чтобы ветки возвращали совместимые типы: число с числом, строку со строкой, ссылку со ссылкой. Смешение ссылок разных справочников в одних ветках допустимо (получится составной тип), но строка рядом с числом вызовет ошибку либо неявное приведение с потерей данных.

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

Типичные ошибки
01
Условия расположены от общего к частному — частные случаи никогда не срабатывают, потому что их перехватывает более широкое условие выше
02
Нет ИНАЧЕ — непокрытые строки получают NULL, который затем ломает суммирование и соединения
03
Проверяется только ЕСТЬ NULL, а пустые ссылки игнорируются — в отчёте появляются строки без подстановки
04
В ветках смешаны несовместимые типы (строка и число) — ошибка выполнения или неявное приведение
05
Пропущено слово КОНЕЦ или КАК для псевдонима поля — запрос не проходит проверку синтаксиса

Проверка результата и отладка

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

Полезный приём — временно заменить текстовые значения в ТОГДА на номера веток («1», «2», «3»). Если в результате встречается номер, которого вы не ожидали, значит условие сформулировано неверно или расположено не на своём месте. После отладки номера заменяются боевыми значениями.

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

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

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

Колонка с вычисляемым значением
Норма

Каждая строка содержит одно из ожидаемых значений

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

Есть NULL или значения, которых нет ни в одной ветке

Строки на границах диапазонов
Норма

Значения ровно на пороге попадают в нужную категорию

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

Пограничные строки классифицированы неверно — проверьте знаки сравнения

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

NULL заменён значением по умолчанию

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

Пустые ячейки — условие ЕСТЬ NULL отсутствует или не сработало

Время выполнения
Норма

Запрос выполняется сопоставимо с версией без ВЫБОР

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

Резкое замедление — конструкция попала в условие соединения или обрабатывает избыточный объём

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

Частые вопросы

Чем ВЫБОР КОГДА отличается от ЕСЛИ во встроенном языке?

ВЫБОР КОГДА выполняется на стороне СУБД внутри запроса и обрабатывает всю выборку за один проход. ЕСЛИ работает в коде при построчном обходе результата. Для отчётов предпочтителен ВЫБОР КОГДА: он не требует обхода выборки и доступен в СКД без программирования.

Можно ли использовать ВЫБОР КОГДА без ИНАЧЕ?

Да, синтаксис это допускает. Но строки, не попавшие ни под одно условие, получат NULL. Если такое поведение не нужно осознанно, всегда добавляйте ИНАЧЕ — это страхует от скрытых пропусков данных.

Сколько условий КОГДА можно указать?

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

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

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

Как сравнить поле с несколькими значениями в одном условии?

Используйте оператор В: КОГДА Товары.ВидНоменклатуры В (&СписокВидов) ТОГДА ... — параметр передаётся как список значений или массив. Это компактнее, чем цепочка условий через ИЛИ.

Почему ВЫБОР КОГДА возвращает NULL, хотя ИНАЧЕ указан?

Чаще всего дело не в конструкции, а в данных: проверьте, не смешаны ли типы в ветках и не приходит ли NULL из самого условия. Сравнение с NULL всегда даёт неопределённый результат, поэтому NULL-поля нужно сначала обработать через ЕСТЬ NULL или ЕСТЬNULL.

Итог

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

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