В языке запросов 1С:Предприятие конструкции ВЫБОР КОГДА и ВЫБОР КАК решают схожие задачи, но работают по-разному. Новичков часто смущает их внешнее сходство с оператором CASE WHEN из SQL, а опытные разработчики спорят о производительности. На практике выбор между ними зависит от цели: нужно ли вам условное ветвление (как в программировании) или преобразование данных (как в отчётах).

В этой статье разберём ключевое отличие: «ВЫБОР КОГДА» проверяет условия последовательно и возвращает первое истинное значение, а «ВЫБОР КАК» просто сопоставляет выражение с вариантами. Покажем, как это влияет на читаемость кода, скорость выполнения запроса и даже на возможность использования в разных версиях платформы. А ещё — типичные ошибки, которые ведут к неверным результатам или падению производительности.

1. Синтаксис: как устроены конструкции

Начнём с базового синтаксиса. Обе конструкции используют ключевое слово ВЫБОР, но далее их логика расходится:

  • 🔹 ВЫБОР КОГДА <Условие1> ТОГДА <Значение1> ... ИНАЧЕ <ЗначениеПоУмолчанию> — работает как цепочка IF-ELSE, проверяя условия по порядку.
  • 🔹 ВЫБОР КАК <Выражение> ТОГДА <Значение1>, <Выражение> ТОГДА <Значение2> ... ИНАЧЕ <ЗначениеПоУмолчанию> — сравнивает одно выражение с несколькими вариантами.

Пример для ВЫБОР КОГДА:

ВЫБОР

КОГДА Документ.СуммаДокумента > 100000 ТОГДА "Крупный"

КОГДА Документ.СуммаДокумента > 50000 ТОГДА "Средний"

ИНАЧЕ "Мелкий"

КОНЕЦ

Тот же результат через ВЫБОР КАК невозможен — здесь нужен другой подход. Зато он идеален для сопоставления дискретных значений:

ВЫБОР

КАК Документ.ВидДокумента ТОГДА

"Заказ клиента" ТОГДА "Продажа",

"Поступление" ТОГДА "Закупка",

"Оплата" ТОГДА "Финансы"

ИНАЧЕ "Прочее"

КОНЕЦ

📊 Какой конструкцией вы чаще пользуетесь в запросах 1С?
ВЫБОР КОГДА
ВЫБОР КАК
Обе одинаково
Не знаю разницы

2. Когда использовать «ВЫБОР КОГДА»

Эта конструкция незаменима, если:

  • 📌 Нужно проверять диапазоны значений (например, суммы, даты, количества).
  • 📌 Условия взаимозависимы и порядок проверки важен (как в IF-ELSEIF).
  • 📌 Требуется динамическая логика, где условия вычисляются в runtime.

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

ВЫБОР

КОГДА Клиент.ОбщаяСуммаПокупок > 500000 ТОГДА "VIP"

КОГДА Клиент.ОбщаяСуммаПокупок > 100000 ТОГДА "Премиум"

КОГДА Клиент.ДатаПоследнейПокупки > ТекущаяДата() - 30 ТОГДА "Активный"

ИНАЧЕ "Стандартный"

КОНЕЦ КАК СегментКлиента

Важно: условия проверяются по порядку, и как только находит первое истинное, дальнейшие проверки игнорируются. Это позволяет оптимизировать запрос, ставя самые «дешёвые» условия вперёд.

💡

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

3. Когда использовать «ВЫБОР КАК»

Эта конструкция эффективна для:

  • 🔍 Сопоставления с фиксированными значениями (как оператор switch в программировании).
  • 🔍 Преобразования кодов в читаемые метки (например, коды видов документов в их названия).
  • 🔍 Работы с перечислениями или справочниками с небольшим количеством элементов.

Пример: преобразование статуса заказа из числового кода в текст:

ВЫБОР

КАК Заказ.Статус ТОГДА

1 ТОГДА "Новый",

2 ТОГДА "В обработке",

3 ТОГДА "Отгружен",

4 ТОГДА "Оплачен"

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

КОНЕЦ КАК СтатусТекстом

Ключевое преимущество — компактность и предсказуемость. Но если вариантов много (более 10), лучше использовать соединение со справочником — это ускорит выполнение.

Что быстрее

ВЫБОР КАК с 20 вариантами или соединение со справочником?:

При большом количестве вариантов (1С:Предприятие начинает тормозить при ~15-20 строках в ВЫБОР КАК) соединение со справочником через ЛЕВОЕ СОЕДИНЕНИЕ будет эффективнее. Оптимизатор запросов лучше работает с табличными данными, чем с длинными списками условий.

4. Производительность: что работает быстрее

Скорость выполнения зависит от контекста:

КритерийВЫБОР КОГДАВЫБОР КАК
Количество условийМедленнее при >5 условийМедленнее при >10 вариантов
Тип условийЛучше для диапазоновЛучше для точных совпадений
ИндексыНе используетНе использует
ЧитаемостьХуже при сложной логикеЛучше для простых сопоставлений

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

ВЫБОР

КОГДА Документ.Вид = 1 ТОГДА "Заказ"

КОГДА Документ.Вид = 2 ТОГДА "Реализация"

...

КОНЕЦ

Лучше написать:

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыДокументов КАК Виды

ПО Документ.Вид = Виды.Ссылка

💡

Для критических по скорости запросов (например, в отчётах с большими объёмами данных) избегайте длинных цепочек ВЫБОР КОГДА. Замените их на соединения с предварительно подготовленными справочниками.

5. Типичные ошибки и как их избежать

Даже опытные разработчики иногда допускают ошибки:

  • Пропущенное ИНАЧЕ — если ни одно условие не сработает, запрос вернёт NULL, что может исказить результаты.
  • Порядок условий — в ВЫБОР КОГДА более общее условие должно идти после частных, иначе оно «перехватит» все случаи.
  • Сравнение с NULL — используйте ЕСТЬ NULL, а не = NULL.

Пример ошибки с порядком:

// НЕПРАВИЛЬНО: условие "Сумма > 0" перекрывает все остальные

ВЫБОР

КОГДА Документ.Сумма > 0 ТОГДА "Положительный"

КОГДА Документ.Сумма > 1000 ТОГДА "Крупный" // Никогда не сработает!

ИНАЧЕ "Отрицательный"

КОНЕЦ

Исправленный вариант:

ВЫБОР

КОГДА Документ.Сумма > 1000 ТОГДА "Крупный"

КОГДА Документ.Сумма > 0 ТОГДА "Положительный"

ИНАЧЕ "Отрицательный"

КОНЕЦ

1. Все ли условия в ВЫБОР КОГДА взаимно исключают друг друга?

2. Есть ли блок ИНАЧЕ для обработки неожиданных значений?

3. Не дублируются ли условия (например, проверка одного и того же диапазона)?

4. Можно ли заменить конструкцию на соединение со справочником для ускорения?-->

6. Совместимость с версиями 1С

Обе конструкции поддерживаются во всех актуальных версиях платформы (1С:Предприятие 8.3 и новее), но есть нюансы:

  • 🔧 В 1С 7.7 аналогичной функциональности нет — там использовались другие подходы.
  • 🔧 В 8.2 синтаксис идентичен, но оптимизатор запросов работал хуже с длинными цепочками условий.
  • 🔧 В 8.3.20+ добавлена поддержка ВЫБОР КОГДА в вычисляемых полях отчётов на СКД.

Для старых конфигураций (например, 1С:Бухгалтерия 2.0) проверяйте совместимость в документации. В современных решениях (1С:ERP, 1С:УТ 11) обе конструкции работают стабильно.

💡

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

7. Альтернативы: когда не нужно использовать ВЫБОР

Иногда задачу можно решить проще:

  • 🔄 Функции ВЫРАЗИТЬ() или ПРЕОБРАЗОВАТЬ() — для преобразования типов данных.
  • 🔄 Соединение с таблицей — если вариантов много, лучше присоединить справочник.
  • 🔄 Вычисляемые поля — в отчётах СКД можно использовать формулы без ВЫБОР.

Пример: вместо

ВЫБОР

КАК Документ.Вид ТОГДА

"ЗаказКлиента" ТОГДА "Заказ",

"РеализацияТоваровУслуг" ТОГДА "Продажа"

ИНАЧЕ ""

КОНЕЦ КАК ТипДокумента

Можно написать:

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыДокументов КАК Виды

ПО Документ.Вид = Виды.Ссылка

Это не только ускорит запрос, но и сделает его более поддерживаемым — при добавлении нового вида документа не придётся править код.

8. Практические примеры из реальных задач

Рассмотрим два кейса из практики:

Задача 1: Классифицировать клиентов по сумме покупок за год.

ВЫБРАТЬ

Клиент.Наименование,

ВЫБОР

КОГДА СУММА(Документ.СуммаДокумента) > 1000000 ТОГДА "VIP"

КОГДА СУММА(Документ.СуммаДокумента) > 500000 ТОГДА "Премиум"

ИНАЧЕ "Стандартный"

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

ИЗ

Справочник.Клиенты КАК Клиент

ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказыКлиентов КАК Документ

ПО Клиент.Ссылка = Документ.Клиент

ГДЕ

Документ.Дата МЕЖДУ &НачалоГода И &КонецГода

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

Клиент.Наименование

Задача 2: Заменить коды видов операций на их названия в отчёте.

ВЫБРАТЬ

Документ.Номер,

ВЫБОР

КАК Документ.ВидОперации ТОГДА

"01" ТОГДА "Поступление",

"02" ТОГДА "Списание",

"03" ТОГДА "Перемещение"

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

КОНЕЦ КАК ВидОперацииТекстом

ИЗ

Документ.Операции КАК Документ

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

1. Перенесите логику в виртуальную таблицу или регистр сведений.

2. Используйте предварительную агрегацию данных (например, через временные таблицы).

3. Если условия статичны, создайте справочник классификаций и присоединяйте его.—>

FAQ: Ответы на частые вопросы

Можно ли вложить один ВЫБОР в другой?

Да, но это усложняет поддержку кода. Пример:

ВЫБОР

КОГДА Документ.Тип = "Заказ" ТОГДА

ВЫБОР

КОГДА Документ.Сумма > 10000 ТОГДА "Крупный заказ"

ИНАЧЕ "Мелкий заказ"

КОНЕЦ

ИНАЧЕ "Другой документ"

КОНЕЦ

Лучше разбить на отдельные вычисляемые поля или использовать соединения.

Почему запрос с ВЫБОР КОГДА работает медленно?

Скорее всего, из-за:

  • 🐢 Слишком большого количества условий (оптимально — не более 5).
  • 🐢 Сложных вычислений в условиях (например, подзапросов).
  • 🐢 Отсутствия индексов на полях, используемых в условиях.

Решение: перенесите логику в соединение со справочником или используйте временные таблицы.

Как в ВЫБОР КАК проверить несколько значений для одного варианта?

Используйте В():

ВЫБОР

КАК Документ.Статус ТОГДА

В("Новый", "В работе") ТОГДА "Активный",

"Завершён" ТОГДА "Архивный"

ИНАЧЕ "Прочий"

КОНЕЦ

Можно ли использовать ВЫБОР в параметрах запроса?

Нет, конструкции ВЫБОР КОГДА/ВЫБОР КАК работают только в теле запроса (в списке полей или условиях). Для динамических параметров используйте:

  • 🔧 Вычисляемые поля в отчётах СКД.
  • 🔧 Программную обработку результатов запроса.
Есть ли разница между ВЫБОР и CASE WHEN в SQL?

В ВЫБОР КОГДА полностью аналогичен CASE WHEN в SQL, а ВЫБОР КАК — это упрощённая форма CASE для точного сопоставления. В некоторых СУБД (например, PostgreSQL) есть оптимизации для CASE, но в разницы в производительности между этими формами нет.

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