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

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

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

Как использовать вложенный ВЫБОР КОГДА в запросе 1С: синтаксис, примеры кода, типичные ошибки, альтернативы и проверка результата в консоли запросов.

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

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

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

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

Условия в КОГДА — это обычные логические выражения языка запросов: сравнения, проверки на NULL, IN, ПОДОБНО. Платформа вычисляет их сверху вниз и возвращает значение первой сработавшей ветки, поэтому порядок условий имеет значение: более частные проверки ставят выше общих.

ВЫБОР

КОГДА Продажи.Сумма > 100000

ТОГДА "Крупная"

КОГДА Продажи.Сумма > 10000

ТОГДА "Средняя"

ИНАЧЕ "Мелкая"

КОНЕЦ КАК КатегорияСделки

Как написать вложенный ВЫБОР: рабочий пример

Типовая задача: классифицировать номенклатуру сначала по виду (товар или услуга), а внутри товаров — ещё и по признаку серийного учёта. Здесь внутренний ВЫБОР помещается в ветку ТОГДА внешнего.

ВЫБОР

КОГДА Номенклатура.ВидНоменклатуры = &ВидТовар

ТОГДА ВЫБОР

КОГДА Номенклатура.ВестиУчетПоСериям

ТОГДА "Товар с сериями"

ИНАЧЕ "Обычный товар"

КОНЕЦ

ИНАЧЕ "Услуга"

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

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

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

Типы данных и NULL: где вложенность ломается

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

Вторая ловушка — NULL. Если условие сравнивает поле, содержащее NULL, сравнение даёт не ИСТИНА и не ЛОЖЬ, а NULL, и ветка не срабатывает. Во вложенной конструкции это каскадируется: внешнее условие не сработало, управление ушло в ИНАЧЕ, хотя логически вы ожидали другого. Защита — функция ЕСТЬNULL вокруг проверяемого поля.

ВЫБОР

КОГДА ЕСТЬNULL(Заказы.СуммаДокумента, 0) > 50000

ТОГДА ВЫБОР

КОГДА Заказы.Оплачен

ТОГДА "Крупный, оплачен"

ИНАЧЕ "Крупный, ждёт оплаты"

КОНЕЦ

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

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

Вложенный ВЫБОР в секциях ИТОГИ, ГДЕ и СГРУППИРОВАТЬ ПО

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

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

Альтернативы вложенному ВЫБОР

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

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

Сравнение подходов

Плоский ВЫБОР с И

Подходит при 2–4 комбинациях условий; ограничение — условия разрастаются при сложной логике

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

Нагляден при двухуровневой иерархии условий; ограничение — плохо сопровождается с третьего уровня

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

Лучший вариант, когда правила классификации меняются пользователями; требует хранить и поддерживать таблицу

ОБЪЕДИНИТЬ простых запросов

Прозрачная логика для непересекающихся множеств; минус — многократное чтение одной таблицы

Типичные ошибки и как их найти

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

Диагностируйте результат в консоли запросов: выведите вычисляемое поле рядом с исходными реквизитами и отсортируйте по нему. Строки с NULL в вычисляемом поле покажут, какие случаи не покрыты условиями. Затем добавьте недостающие ветки или ИНАЧЕ и повторите проверку.

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

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

Выполнение запроса
Норма

Запрос выполняется без синтаксических ошибок

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

Ошибка с указанием позиции в конце текста — ищите незакрытый КОНЕЦ

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

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

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

Есть NULL — не покрыта часть данных, нужна ветка ИНАЧЕ

Группировка и итоги
Норма

Итоги по категориям сходятся с контрольным расчётом

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

Категории дробятся или строки выпадают из итогов

FAQ

Сколько уровней вложенности ВЫБОР поддерживает платформа 1С?

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

Можно ли вкладывать ВЫБОР в ветку ИНАЧЕ, а не ТОГДА?

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

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

Чаще всего причина в NULL в исходных данных: сравнение NULL с любым значением не даёт ИСТИНА, поэтому ветка не срабатывает. Оберните проверяемое поле в ЕСТЬNULL и добавьте ветку ИНАЧЕ как страховку на непредусмотренные значения.

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

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

Что быстрее: вложенный ВЫБОР или соединение с таблицей соответствий?

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

Как отладить сложный вложенный ВЫБОР?

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

Итог

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

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