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

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

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

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

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

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

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

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

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

ВЫБОР

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

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

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

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

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

КОНЕЦ

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

В условиях можно использовать сравнения, МЕЖДУ, В, ПОДОБНО, проверку ЕСТЬ NULL и логические операции И, ИЛИ, НЕ. В качестве возвращаемых значений допустимы поля, литералы, параметры и выражения, включая вложенные конструкции ВЫБОР.

Простой пример: статус по условию

Классическая задача — вывести текстовый статус документа в зависимости от его признаков, не вычисляя его в коде при обходе выборки:

ВЫБРАТЬ

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

ВЫБОР

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

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

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

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

ИНАЧЕ "Черновик"

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

ИЗ

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

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

Результат такого запроса можно сразу выводить в отчёт или динамический список: поле Статус будет обычным строковым полем, доступным для группировки, отбора и оформления.

Вычисляемые числовые значения и агрегаты

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

ВЫБРАТЬ

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

СУММА(ВЫБОР

КОГДА Остатки.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)

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

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

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

ИЗ

РегистрНакопления.ТоварыНаСкладах КАК Остатки

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

Остатки.Номенклатура

Здесь ВЫБОР находится внутри агрегатной функции СУММА — это допустимо и очень удобно: не нужно делать два отдельных запроса и объединять их. Аналогично считают выручку с учётом возвратов, количество документов по признаку и прочие условные показатели.

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

Замена NULL и ЕСТЬNULL против ВЫБОР

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

ВЫБОР

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

ТОГДА 0

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

КОНЕЦ

Функционально оба варианта эквивалентны. ЕСТЬNULL короче и читается легче, поэтому для простой замены NULL предпочтительна. ВЫБОР оправдан, когда условий несколько или нужно проверять не только NULL, но и, например, нулевое значение.

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

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

Короткая замена NULL на конкретное значение. Подходит, когда условие одно — проверка на NULL. Ограничение: только два варианта результата.

ВЫБОР КОГДА

Несколько условий любой сложности, разные выражения в ветках. Подходит для статусов, коэффициентов, условных агрегатов. Минус: более громоздкий текст.

Соединение с таблицей значений

Используется, когда вариантов подстановки много и они хранятся в данных (например, соответствие статусов текстам). Для 2–3 вариантов избыточно.

ВЫБОР в СКД и динамических списках

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

В динамических списках с произвольным запросом ВЫБОР позволяет выводить колонки, которых нет в данных напрямую: например, колонку «Просрочен» на основании сравнения даты документа с текущей датой через функцию &ТекущаяДата, переданную параметром.

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

Типичные ошибки и ограничения

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

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

Третья группа ошибок — ловушки с NULL в условиях. Сравнение Поле = Значение для NULL-поля даёт не ИСТИНА и не ЛОЖЬ, а неопределённость, и ветка не сработает. Проверку на NULL делайте только через ЕСТЬ NULL, а в условиях с полями из левых соединений сначала оборачивайте их в ЕСТЬNULL.

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

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

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

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

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

Значения вычисляемого поля в выборке
Норма

Все строки имеют осмысленное значение из ожидаемого набора

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

Встречаются NULL или значения, которых не должно быть

Отбор по вычисляемому полю
Норма

Отбор по каждому значению возвращает ожидаемые строки

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

Часть строк не попадает ни под одно значение отбора

Итоги при агрегации с ВЫБОР
Норма

Суммы совпадают с контрольным отчётом или расчётом вручную на малом примере

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

Итоги расходятся — ошибка в условии или знаке

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

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

Можно ли вкладывать ВЫБОР внутрь ВЫБОР?

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

Работает ли ВЫБОР в секции ИМЕЮЩИЕ и УПОРЯДОЧИТЬ ПО?

Да. Конструкцию можно использовать в ИМЕЮЩИЕ для фильтрации групп и в УПОРЯДОЧИТЬ ПО для сортировки по вычисляемому значению. Чаще всего проще дать полю псевдоним через КАК и ссылаться на него.

Что вернёт ВЫБОР, если ни одно условие не выполнено и ИНАЧЕ нет?

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

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

Да, параметры (&Параметр) допустимы и в условиях, и в возвращаемых значениях. Это удобно для настраиваемых порогов: например, границы сумм для категорий «крупная/мелкая» передаются параметром, а не зашиваются в текст запроса.

Чем ВЫБОР отличается от условного оператора «Если» в коде 1С?

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

Почему ВЫБОР возвращает NULL, хотя условие должно срабатывать?

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

Итог

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

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