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

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

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

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

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

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

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

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

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

ВЫБОР

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

КОГДА Продажи.Сумма >= 10000 ТОГДА "Средний заказ"

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

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

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

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

Несколько условий через повторяющиеся КОГДА

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

ВЫБОР

КОГДА Заказы.СуммаДокумента >= 500000 ТОГДА 15

КОГДА Заказы.СуммаДокумента >= 100000 ТОГДА 10

КОГДА Заказы.СуммаДокумента >= 50000 ТОГДА 5

ИНАЧЕ 0

КОНЕЦ КАК ПроцентСкидки

В этом примере заказ на 120 000 попадёт во вторую ветку: первое условие ложно, второе истинно, третья ветка уже не проверяется. Если бы ветки шли в обратном порядке — от маленьких сумм к большим, — заказ на 120 000 зацепился бы за условие «больше 50000» раньше и получил скидку 5 вместо 10. Ошибки такого рода не вызывают исключений и обнаруживаются только при ручной сверке цифр.

Количество веток КОГДА не ограничено практически, однако конструкции с десятками условий тяжело читаются и медленнее отлаживаются. Если логика разрастается, лучше перенести соответствие «значение → результат» в регистр сведений или перечисление и получать его соединением, а не размножать ветки.

Комбинация нескольких условий в одной ветке

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

ВЫБОР

КОГДА Долги.ДнейПросрочки > 30 И Долги.Сумма > 100000 ТОГДА "Критично"

КОГДА Долги.ДнейПросрочки > 30 ИЛИ Долги.Сумма > 100000 ТОГДА "Внимание"

ИНАЧЕ "Норма"

КОНЕЦ КАК СтатусДолга

При смешении И и ИЛИ всегда расставляйте скобки явно. Приоритет операторов (И выше ИЛИ) совпадает с общепринятым, но запрос читают и другие разработчики, а скобки исключают двусмысленность и ошибки при последующих правках.

Условия могут включать проверку на NULL через ЕСТЬ NULL, вхождение в список через В, сравнение с параметром запроса и даже вложенные подзапросы. Чем сложнее условие, тем важнее протестировать его на граничных значениях: нулевой сумме, пустой дате, незаполненной ссылке.

Вложенные конструкции ВЫБОР

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

ВЫБОР

КОГДА Контрагенты.ЮрФизЛицо = ЗНАЧЕНИЕ(Перечисление.ЮрФизЛицо.ЮрЛицо) ТОГДА

ВЫБОР

КОГДА Контрагенты.Оборот > 1000000 ТОГДА "ЮЛ крупный"

ИНАЧЕ "ЮЛ стандарт"

КОНЕЦ

ИНАЧЕ

ВЫБОР

КОГДА Контрагенты.Оборот > 300000 ТОГДА "ФЛ крупный"

ИНАЧЕ "ФЛ стандарт"

КОНЕЦ

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

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

Альтернатива вложенности — плоская цепочка КОГДА с составными условиями через И. Для двух-трёх комбинаций плоский вариант обычно короче и понятнее; вложенность оправдана, когда внутри групп свои независимые шкалы.

Как оформить сложную логику

Плоская цепочка КОГДА с И/ИЛИ

Подходит для 3–6 комбинаций, легко читается. Ограничение: условия дублируют общие части, при росте числа веток появляются повторы.

Вложенный ВЫБОР

Подходит для иерархической логики «группа → градация внутри». Ограничение: больше двух уровней тяжело отлаживать.

Соединение с регистром соответствий

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

ВЫБОР в условиях, группировках и итогах

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

В группировках СГРУППИРОВАТЬ ПО конструкция применяется для агрегации по категориям: например, посчитать сумму продаж в разрезе «мелкий/средний/крупный». Тогда та же конструкция указывается и в списке полей, и в группировке, а агрегатная функция СУММА считается уже по вычисленной категории.

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

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

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

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

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

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

Проверка результата перед передачей в отчёт

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

Сверку делайте вручную: для каждой записи посчитайте ожидаемую категорию на бумаге и сравните с тем, что вернул запрос. Особое внимание — граничным значениям: сумме ровно 100000 при условии «больше или равно 100000», нулевой просрочке, дате, равной текущей.

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

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

Каждая ветка КОГДА
Норма

В выборке есть хотя бы одна запись, попавшая в эту ветку, и значение соответствует ручному расчёту

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

Ветка пустая на тестовых данных или значения не совпадают с расчётом

Границы диапазонов
Норма

Значение ровно на границе попадает в задуманную ветку (проверьте строгость сравнения)

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

Граничное значение уходит не в ту ветку — перепутаны > и >=

Записи с пустыми реквизитами
Норма

Такие записи попадают в ИНАЧЕ или обрабатываются явно

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

Поле содержит NULL, ячейки пустые

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

Во всех строках поле одного типа

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

Часть строк числовые, часть строковые

Частые вопросы о ВЫБОР КОГДА ТОГДА в 1С

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

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

Как сравнить несколько значений одного поля без длинной цепочки ИЛИ?

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

Работает ли ВЫБОР в СКД и чем он отличается от вычисляемых полей?

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

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

Проверьте, с чем сравниваете. Пустая ссылка сравнивается через ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка), а NULL после левого соединения — только через ЕСТЬ NULL. Если реквизит составного типа и не заполнен, сравнение с пустой ссылкой конкретного типа тоже может не сработать — надёжнее проверять через ЕСТЬNULL и представление.

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

Незначительно: вычисление условий дешёвое по сравнению с соединениями и сканированием таблиц. Производительность падает, если сама конструкция используется в секции ГДЕ или соединении — тогда СУБД не может применить индексы. В списке полей даже десятки веток практически не влияют на время выполнения.

Можно ли вернуть из ВЫБОР значение перечисления или ссылку?

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

Итог

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

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