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

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

Синтаксис конструкции «Когда…Тогда» в 1С

Разбираем синтаксис конструкции «Когда…Тогда…Иначе…Конец» в 1С: примеры в запросах, СКД, вычисляемых полях и типичные ошибки разработчиков.

Конструкция «Когда…Тогда…Иначе…Конец» — это аналог оператора CASE в языке запросов 1С и встроенных выражениях. Она позволяет выбирать значение в зависимости от условий прямо в тексте запроса, без постобработки результата в коде. Такой подход упрощает отчёты, сокращает объём программного кода и ускоряет выборку, потому что вся логика выполняется на стороне СУБД.

Важно понимать: «Когда…Тогда» работает именно в языке запросов и в некоторых выражениях (например, в СКД, в вычисляемых полях динамических списков). В обычном программном коде на встроенном языке 1С используется оператор «Если…Тогда…Иначе…КонецЕсли» — это другая конструкция, и путать их нельзя. Новички часто пытаются вставить «Когда» в модуль объекта и получают синтаксическую ошибку.

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

Базовый синтаксис конструкции

Полная форма записи выглядит так: ключевое слово «ВЫБОР», затем одна или несколько пар «КОГДА условие ТОГДА значение», необязательная ветка «ИНАЧЕ значение» и завершающее слово «КОНЕЦ». В русскоязычном синтаксисе допустимы и английские ключевые слова: CASE, WHEN, THEN, ELSE, END — платформа понимает оба варианта.

ВЫБРАТЬ

Номенклатура.Наименование,

ВЫБОР

КОГДА Номенклатура.Цена > 10000

ТОГДА "Дорогой товар"

КОГДА Номенклатура.Цена > 1000

ТОГДА "Средний сегмент"

ИНАЧЕ "Бюджетный товар"

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

ИЗ

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

Условия проверяются последовательно сверху вниз. Как только одно из них оказалось истинным, возвращается соответствующее значение, а остальные ветки не вычисляются. Поэтому порядок условий имеет значение: более строгие проверки должны стоять выше. В примере выше условие «цена больше 10000» стоит первым — если поменять ветки местами, дорогие товары попадут в «Средний сегмент», потому что проверка «больше 1000» сработает раньше.

Если ни одно условие не выполнилось и ветка «Иначе» отсутствует, результатом будет значение NULL. Это частая причина неожиданных пустых колонок в отчётах: разработчик забыл «Иначе», а часть данных не подпала ни под одно условие.

bsl
ВЫБОР
	КОГДА Продажи.Сумма >= 100000 ТОГДА "Крупная"
	КОГДА Продажи.Сумма >= 10000 ТОГДА "Средняя"
	ИНАЧЕ "Мелкая"
КОНЕЦ КАК КатегорияСделки

Когда использовать «Когда…Тогда», а когда «Если…Тогда»

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

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

Сравнение вариантов

ВЫБОР…КОГДА…ТОГДА…КОНЕЦ

Только в запросах и выражениях СКД. Выполняется на СУБД, доступен для группировок и отборов отчёта. Не работает в модулях.

Если…Тогда…КонецЕсли

Оператор встроенного языка в модулях. Подходит для логики проведения, обработки данных, интерактива. Требует обхода выборки в коде.

Тернарный оператор ?(условие, а, б)

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

Несколько условий и вложенные конструкции

Количество веток «КОГДА…ТОГДА» не ограничено, но на практике больше пяти-семи условий делают запрос трудночитаемым. Если вариантов много и они зависят от одного справочного значения, часто удобнее соединением (ЛЕВОЕ СОЕДИНЕНИЕ) подтянуть нужное значение из таблицы, чем перечислять десятки веток.

Допускается вложение одной конструкции «ВЫБОР» внутрь другой — например, когда сначала проверяется вид документа, а внутри каждого вида — дополнительное условие. Такой приём работает, но быстро снижает читаемость. При вложенности глубже двух уровней стоит пересмотреть логику: возможно, часть условий можно объединить через И/ИЛИ в одной ветке.

ВЫБОР

КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.Закрыт)

ТОГДА "Завершён"

КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.ВРаботе)

И Заказы.ДатаОтгрузки < &ТекущаяДата

ТОГДА "Просрочен"

КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.ВРаботе)

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

ИНАЧЕ "Новый"

КОНЕЦ КАК СостояниеЗаказа

Обратите внимание на сравнение с перечислением: значения перечислений в запросе указываются через функцию ЗНАЧЕНИЕ с полным именем. Попытка сравнить поле со строкой «Закрыт» не даст ошибки синтаксиса, но условие никогда не выполнится — типы не совпадут.

Применение в отчётах на СКД

В системе компоновки данных «Когда…Тогда» используется в двух местах: в тексте запроса набора данных и в вычисляемых полях на закладке «Вычисляемые поля» конструктора СКД. Вычисляемое поле удобно, когда базовый запрос менять нежелательно — например, он типовой, а отчёт дорабатывается под конкретную задачу.

Выражение вычисляемого поля пишется на том же языке выражений компоновки: «Выбор Когда Условие Тогда Значение Иначе Значение2 Конец». После добавления поле становится доступным в ресурсах, группировках и отборах отчёта. Например, можно вычислить поле «ПериодПросрочки» и сгруппировать по нему должников контрагентов.

Порядок действий для вычисляемого поля в СКД
  1. 1
    Откройте схему компоновки данных отчёта и перейдите на закладку «Вычисляемые поля».
  2. 2
    Добавьте поле, задайте путь к данным, например «КатегорияДолга».
  3. 3
    В колонке «Выражение» впишите конструкцию: Выбор Когда ДниПросрочки > 90 Тогда "Свыше 90" Когда ДниПросрочки > 30 Тогда "30–90" Иначе "До 30" Конец.
  4. 4
    Убедитесь, что поле ДниПросрочки присутствует в наборе данных, иначе получите ошибку «Поле не найдено».
  5. 5
    Добавьте новое поле в настройки отчёта (ресурсы или группировку) и сформируйте отчёт для проверки.

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

Работа с NULL и особые случаи

Значение NULL в запросах 1С требует отдельного внимания. Сравнение «Поле = NULL» не работает так, как ожидается: корректная проверка — «Поле ЕСТЬ NULL». Внутри «КОГДА» это пишется как обычное условие: «КОГДА Остатки.Склад ЕСТЬ NULL ТОГДА "Без склада"».

Полезный приём — использовать «ВЫБОР» для замены NULL на значение по умолчанию при левом соединении, вместо функции ЕСТЬNULL. Оба варианта рабочие: ЕСТЬNULL(Поле, 0) короче, но «ВЫБОР» гибче, когда заменяющее значение зависит от дополнительного условия.

ВЫБОР

КОГДА Цены.Цена ЕСТЬ NULL

ТОГДА 0

КОГДА Цены.Цена < 0

ТОГДА 0

ИНАЧЕ Цены.Цена

КОНЕЦ КАК ЦенаДляРасчёта

Типичные ошибки и их диагностика

Первая и самая частая ошибка — попытка использовать «Когда…Тогда» в программном коде модуля. Платформа выдаст синтаксическую ошибку, потому что во встроенном языке такой конструкции нет. Второй типичный промах — пропущенное «КОНЕЦ» или «ИНАЧЕ» без завершающего слова: конструктор запроса сообщит о нарушении структуры.

Третья группа ошибок связана с типами: возврат строки в одной ветке и числа в другой, сравнение ссылки со строкой, сравнение с перечислением без ЗНАЧЕНИЕ(). Такие ошибки часто не ловятся на этапе проверки запроса и проявляются только на реальных данных — поэтому тестируйте запрос на выборке, где встречаются все ветки условий.

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

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

Все записи результата заполнены в вычисляемой колонке
Норма

Нет пустых значений либо пустоты объяснимы логикой

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

Пустые ячейки у записей, которые должны были попасть в ветку ИНАЧЕ

Каждая ветка условия срабатывает
Норма

В тестовой выборке есть записи по каждой категории

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

Одна из категорий отсутствует хотя данные для неё есть — проверьте порядок условий

Типы значений в колонке
Норма

Все значения одного типа

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

Смешение строк и чисел — унифицируйте типы в ветках

FAQ: частые вопросы по конструкции «Когда…Тогда»

Чем «Когда…Тогда» отличается от «Если…Тогда» в 1С?

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

Обязательна ли ветка «Иначе»?

Нет, ветка «Иначе» необязательна. Но если ни одно условие не выполнится и «Иначе» отсутствует, результатом будет NULL. В отчётах это проявляется как пустые ячейки, поэтому ветку «Иначе» рекомендуется указывать всегда, даже с нейтральным значением вроде пустой строки или нуля.

Можно ли использовать «Когда…Тогда» в условии ГДЕ?

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

Почему условие с перечислением не срабатывает?

Скорее всего, значение перечисления указано строкой («"Закрыт"») вместо функции ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.Закрыт). Типы не совпадают, сравнение всегда ложно, и запрос не выдаёт ошибку. Исправьте сравнение на ЗНАЧЕНИЕ с полным именем значения перечисления.

Есть ли ограничение на количество условий «Когда»?

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

Работает ли «Когда…Тогда» в динамических списках?

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

Итог

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

«Когда…Тогда…Иначе…Конец» — конструкция языка запросов и СКД, в коде модулей используется «Если…Тогда». Условия проверяются сверху вниз, поэтому частные случаи ставьте выше общих. Всегда добавляйте «Иначе», следите за совместимостью типов возвращаемых значений и сравнивайте перечисления через ЗНАЧЕНИЕ(). При большом числе веток выносите соответствия в данные, а не в текст запроса.