Разработка и Конфигурация · 11 мин
Синтаксис конструкции «Когда…Тогда» в 1С
Разбираем синтаксис конструкции «Когда…Тогда…Иначе…Конец» в 1С: примеры в запросах, СКД, вычисляемых полях и типичные ошибки разработчиков.
Конструкция «Когда…Тогда…Иначе…Конец» — это аналог оператора CASE в языке запросов 1С и встроенных выражениях. Она позволяет выбирать значение в зависимости от условий прямо в тексте запроса, без постобработки результата в коде. Такой подход упрощает отчёты, сокращает объём программного кода и ускоряет выборку, потому что вся логика выполняется на стороне СУБД.
Важно понимать: «Когда…Тогда» работает именно в языке запросов и в некоторых выражениях (например, в СКД, в вычисляемых полях динамических списков). В обычном программном коде на встроенном языке 1С используется оператор «Если…Тогда…Иначе…КонецЕсли» — это другая конструкция, и путать их нельзя. Новички часто пытаются вставить «Когда» в модуль объекта и получают синтаксическую ошибку.
Ниже разобран полный синтаксис конструкции, варианты с несколькими условиями, применение в отчётах на СКД, ограничения по типам данных и типичные ошибки с примерами исправления.
Базовый синтаксис конструкции
Полная форма записи выглядит так: ключевое слово «ВЫБОР», затем одна или несколько пар «КОГДА условие ТОГДА значение», необязательная ветка «ИНАЧЕ значение» и завершающее слово «КОНЕЦ». В русскоязычном синтаксисе допустимы и английские ключевые слова: CASE, WHEN, THEN, ELSE, END — платформа понимает оба варианта.
ВЫБРАТЬ
Номенклатура.Наименование,
ВЫБОР
КОГДА Номенклатура.Цена > 10000
ТОГДА "Дорогой товар"
КОГДА Номенклатура.Цена > 1000
ТОГДА "Средний сегмент"
ИНАЧЕ "Бюджетный товар"
КОНЕЦ КАК КатегорияЦены
ИЗ
Справочник.Номенклатура КАК Номенклатура
Условия проверяются последовательно сверху вниз. Как только одно из них оказалось истинным, возвращается соответствующее значение, а остальные ветки не вычисляются. Поэтому порядок условий имеет значение: более строгие проверки должны стоять выше. В примере выше условие «цена больше 10000» стоит первым — если поменять ветки местами, дорогие товары попадут в «Средний сегмент», потому что проверка «больше 1000» сработает раньше.
Если ни одно условие не выполнилось и ветка «Иначе» отсутствует, результатом будет значение NULL. Это частая причина неожиданных пустых колонок в отчётах: разработчик забыл «Иначе», а часть данных не подпала ни под одно условие.
ВЫБОР
КОГДА Продажи.Сумма >= 100000 ТОГДА "Крупная"
КОГДА Продажи.Сумма >= 10000 ТОГДА "Средняя"
ИНАЧЕ "Мелкая"
КОНЕЦ КАК КатегорияСделкиКогда использовать «Когда…Тогда», а когда «Если…Тогда»
Главный критерий выбора — место выполнения. «Когда…Тогда» (ВЫБОР…КОГДА) существует только внутри текста запроса, в выражениях компоновки данных, в вычисляемых полях динамических списков и в некоторых других выражениях платформы. «Если…Тогда…КонецЕсли» — оператор встроенного языка, который пишется в модулях: формах, объектах, общих модулях.
Практическое правило: если логика касается отбора или преобразования данных, которые выводятся в отчёт или список, — выносите её в запрос через «ВЫБОР…КОГДА». Так отчёт останется самодостаточным, а настройки СКД смогут использовать вычисленное поле для группировок и отборов. Если же нужно принять решение в процессе проведения документа, обработки результата запроса или интерактивной логике формы — используйте «Если…Тогда» в коде.
Сравнение вариантов
Только в запросах и выражениях СКД. Выполняется на СУБД, доступен для группировок и отборов отчёта. Не работает в модулях.
Оператор встроенного языка в модулях. Подходит для логики проведения, обработки данных, интерактива. Требует обхода выборки в коде.
Краткая форма в коде для простых выборов из двух значений. Не читается при вложенных условиях, в запросах не работает.
Несколько условий и вложенные конструкции
Количество веток «КОГДА…ТОГДА» не ограничено, но на практике больше пяти-семи условий делают запрос трудночитаемым. Если вариантов много и они зависят от одного справочного значения, часто удобнее соединением (ЛЕВОЕ СОЕДИНЕНИЕ) подтянуть нужное значение из таблицы, чем перечислять десятки веток.
Допускается вложение одной конструкции «ВЫБОР» внутрь другой — например, когда сначала проверяется вид документа, а внутри каждого вида — дополнительное условие. Такой приём работает, но быстро снижает читаемость. При вложенности глубже двух уровней стоит пересмотреть логику: возможно, часть условий можно объединить через И/ИЛИ в одной ветке.
ВЫБОР
КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.Закрыт)
ТОГДА "Завершён"
КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.ВРаботе)
И Заказы.ДатаОтгрузки < &ТекущаяДата
ТОГДА "Просрочен"
КОГДА Заказы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.ВРаботе)
ТОГДА "В работе"
ИНАЧЕ "Новый"
КОНЕЦ КАК СостояниеЗаказа
Обратите внимание на сравнение с перечислением: значения перечислений в запросе указываются через функцию ЗНАЧЕНИЕ с полным именем. Попытка сравнить поле со строкой «Закрыт» не даст ошибки синтаксиса, но условие никогда не выполнится — типы не совпадут.
Применение в отчётах на СКД
В системе компоновки данных «Когда…Тогда» используется в двух местах: в тексте запроса набора данных и в вычисляемых полях на закладке «Вычисляемые поля» конструктора СКД. Вычисляемое поле удобно, когда базовый запрос менять нежелательно — например, он типовой, а отчёт дорабатывается под конкретную задачу.
Выражение вычисляемого поля пишется на том же языке выражений компоновки: «Выбор Когда Условие Тогда Значение Иначе Значение2 Конец». После добавления поле становится доступным в ресурсах, группировках и отборах отчёта. Например, можно вычислить поле «ПериодПросрочки» и сгруппировать по нему должников контрагентов.
- 1Откройте схему компоновки данных отчёта и перейдите на закладку «Вычисляемые поля».
- 2Добавьте поле, задайте путь к данным, например «КатегорияДолга».
- 3В колонке «Выражение» впишите конструкцию: Выбор Когда ДниПросрочки > 90 Тогда "Свыше 90" Когда ДниПросрочки > 30 Тогда "30–90" Иначе "До 30" Конец.
- 4Убедитесь, что поле ДниПросрочки присутствует в наборе данных, иначе получите ошибку «Поле не найдено».
- 5Добавьте новое поле в настройки отчёта (ресурсы или группировку) и сформируйте отчёт для проверки.
При использовании «Когда…Тогда» в ресурсах СКД помните про агрегирование: если конструкция применяется к детальным полям, а ресурс суммируется, убедитесь, что результат корректно сворачивается. Частая ситуация — условие рассчитывается на уровне группировки, а данные для него берутся из детальных записей, и итог получается не тем, что ожидал разработчик.
Работа с NULL и особые случаи
Значение NULL в запросах 1С требует отдельного внимания. Сравнение «Поле = NULL» не работает так, как ожидается: корректная проверка — «Поле ЕСТЬ NULL». Внутри «КОГДА» это пишется как обычное условие: «КОГДА Остатки.Склад ЕСТЬ NULL ТОГДА "Без склада"».
Полезный приём — использовать «ВЫБОР» для замены NULL на значение по умолчанию при левом соединении, вместо функции ЕСТЬNULL. Оба варианта рабочие: ЕСТЬNULL(Поле, 0) короче, но «ВЫБОР» гибче, когда заменяющее значение зависит от дополнительного условия.
ВЫБОР
КОГДА Цены.Цена ЕСТЬ NULL
ТОГДА 0
КОГДА Цены.Цена < 0
ТОГДА 0
ИНАЧЕ Цены.Цена
КОНЕЦ КАК ЦенаДляРасчёта
Типичные ошибки и их диагностика
Первая и самая частая ошибка — попытка использовать «Когда…Тогда» в программном коде модуля. Платформа выдаст синтаксическую ошибку, потому что во встроенном языке такой конструкции нет. Второй типичный промах — пропущенное «КОНЕЦ» или «ИНАЧЕ» без завершающего слова: конструктор запроса сообщит о нарушении структуры.
Третья группа ошибок связана с типами: возврат строки в одной ветке и числа в другой, сравнение ссылки со строкой, сравнение с перечислением без ЗНАЧЕНИЕ(). Такие ошибки часто не ловятся на этапе проверки запроса и проявляются только на реальных данных — поэтому тестируйте запрос на выборке, где встречаются все ветки условий.
Как проверить результат
Нет пустых значений либо пустоты объяснимы логикой
Пустые ячейки у записей, которые должны были попасть в ветку ИНАЧЕ
В тестовой выборке есть записи по каждой категории
Одна из категорий отсутствует хотя данные для неё есть — проверьте порядок условий
Все значения одного типа
Смешение строк и чисел — унифицируйте типы в ветках
FAQ: частые вопросы по конструкции «Когда…Тогда»
Чем «Когда…Тогда» отличается от «Если…Тогда» в 1С?
«Когда…Тогда» — часть конструкции ВЫБОР в языке запросов и выражениях СКД, она возвращает значение и выполняется при выборке данных. «Если…Тогда…КонецЕсли» — оператор встроенного языка в модулях, он управляет ходом выполнения программы и ничего не возвращает. Взаимозаменяемы они только концептуально, синтаксически — нет.
Обязательна ли ветка «Иначе»?
Нет, ветка «Иначе» необязательна. Но если ни одно условие не выполнится и «Иначе» отсутствует, результатом будет NULL. В отчётах это проявляется как пустые ячейки, поэтому ветку «Иначе» рекомендуется указывать всегда, даже с нейтральным значением вроде пустой строки или нуля.
Можно ли использовать «Когда…Тогда» в условии ГДЕ?
Да, конструкцию ВЫБОР можно применять в секции ГДЕ, например для сравнения поля с вычисленным по условию значением. Однако чаще ту же логику проще записать обычными логическими операторами И/ИЛИ — запрос будет короче и понятнее оптимизатору СУБД.
Почему условие с перечислением не срабатывает?
Скорее всего, значение перечисления указано строкой («"Закрыт"») вместо функции ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказа.Закрыт). Типы не совпадают, сравнение всегда ложно, и запрос не выдаёт ошибку. Исправьте сравнение на ЗНАЧЕНИЕ с полным именем значения перечисления.
Есть ли ограничение на количество условий «Когда»?
Жёсткого ограничения платформа не накладывает, но с ростом числа веток падает читаемость и может деградировать производительность. Если веток больше пяти-семи и все они сопоставляют одно поле с набором значений, рассмотрите вариант с соединением с таблицей соответствий вместо перечисления условий.
Работает ли «Когда…Тогда» в динамических списках?
Да, если динамический список использует произвольный запрос, конструкция ВЫБОР…КОГДА работает в нём так же, как в обычном запросе. Вычисленное поле можно вывести в колонку списка. Учтите, что по таким полям могут быть ограничения при группировке и поиске в зависимости от настроек списка.
Что важно запомнить
«Когда…Тогда…Иначе…Конец» — конструкция языка запросов и СКД, в коде модулей используется «Если…Тогда». Условия проверяются сверху вниз, поэтому частные случаи ставьте выше общих. Всегда добавляйте «Иначе», следите за совместимостью типов возвращаемых значений и сравнивайте перечисления через ЗНАЧЕНИЕ(). При большом числе веток выносите соответствия в данные, а не в текст запроса.