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

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

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

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

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

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

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

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

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

ВЫБОР

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

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

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

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

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

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

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

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

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

Типичная задача: классифицировать номенклатуру в отчёте. Сначала проверяем вид номенклатуры, а внутри — дополнительное условие по цене или признаку. Вложенная конструкция размещается в ветке ТОГДА внешнего выбора:

ВЫБОР

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

ТОГДА "Услуга"

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

ТОГДА ВЫБОР

КОГДА Товары.Цена >= 50000

ТОГДА "Товар премиум"

ИНАЧЕ "Товар стандарт"

КОНЕЦ

ИНАЧЕ "Прочее"

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

Здесь внешний выбор отсекает услуги и прочие позиции, а вложенный — делит товары на две ценовые категории. Обратите внимание: вложенная конструкция обязана завершаться собственным словом КОНЕЦ, иначе запрос не пройдёт проверку синтаксиса.

Аналогично вложение допустимо в ветке ИНАЧЕ. Такой вариант удобен, когда «всё остальное» нужно дополнительно разделить по признаку, не забивая верхний уровень условиями.

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

Порядок вычисления условий и приоритет проверок

Ключевое правило: условия внутри одного ВЫБОРА проверяются сверху вниз, и срабатывает только первое истинное. Если два условия могут быть истинны одновременно, более частное должно стоять выше более общего. Классическая ошибка — поставить условие «Сумма >= 10000» выше «Сумма >= 100000»: тогда ветка крупных продаж никогда не сработает.

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

При отладке полезно временно вывести результат каждого уровня в отдельное поле запроса. Так видно, на каком уровне строка «сошла с маршрута», и не нужно угадывать, какое условие перехватило строку раньше времени.

Ограничения платформы и влияние на производительность

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

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

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

Типичные ошибки при вложенных выборах

Большинство проблем с вложенными ВЫБОР КОГДА сводится к нескольким повторяющимся сценариям. Их стоит проверять в первую очередь, если результат запроса не совпадает с ожиданиями.

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

Отдельно стоит упомянуть работу с NULL. Если поле в условии может быть NULL (например, после левого соединения), сравнение «Поле = Значение» вернёт не ИСТИНУ и не ЛОЖЬ, а NULL — и ветка просто не сработает. Корректный приём: КОГДА Таблица.Поле ЕСТЬ NULL ТОГДА ... либо предварительная обёртка ЕСТЬNULL(Поле, ЗначениеПоУмолчанию).

Альтернативы вложенным выборам

Не всякую многоуровневую логику стоит реализовывать вложенными ВЫБОР КОГДА. Часто есть более сопровождаемые варианты.

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

Вложенный ВЫБОР КОГДА

Подходит для 2–3 уровней логики с фиксированными условиями. Минус: трудно читать и править при росте числа веток

Соединение со справочником или таблицей соответствий

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

Плоский список КОГДА с составными условиями

Подходит, когда уровней много, но каждая комбинация описывается одним условием через И/ИЛИ. Минус: длинные условия

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

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

Вычисляемые поля СКД

Подходит, когда классификация нужна только в отчёте. Минус: логика не переиспользуется в других запросах

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

Маршрут решения

Как выбрать подход

Уровней вложенности не больше двух и условия стабильныИспользуйте вложенный ВЫБОР КОГДА прямо в запросе
Правила классификации должны менять пользователиСоздайте справочник или регистр соответствий и соединяйтесь с ним
Логика требует промежуточных вычислений или цикловВыполните расчёт на встроенном языке после запроса
Классификация нужна только в одном отчёте на СКДИспользуйте вычисляемое поле СКД вместо усложнения запроса

Проверка результата и отладка

Главный инструмент проверки — консоль запросов на тестовой базе с контролируемыми данными. Подготовьте набор записей, покрывающий каждую ветку обоих уровней, включая граничные значения (ровно на пороге условия) и NULL. Сверьте результат с ожидаемой таблицей вручную.

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

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

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

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

Каждая строка попала в ожидаемую категорию, включая граничные значения

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

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

Наличие NULL в результате
Норма

NULL отсутствуют или обработаны осознанно

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

NULL появляются там, где должна быть категория — отсутствует ИНАЧЕ или поле не обёрнуто в ЕСТЬNULL

Тип поля в СКД
Норма

Тип соответствует ожидаемому, итоги и формат работают

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

Смешанные типы, итоги не считаются — приведите ветки к одному типу

Время выполнения на рабочем объёме
Норма

Запрос выполняется за приемлемое время

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

Резкое замедление — проверяйте условия на функции и соединения внутри ВЫБОРА

Длинные вложенные выборы удобно форматировать отступами: каждый уровень — свой отступ, КОНЕЦ строго под своим ВЫБОРОМ. Это мелочь, но именно она спасает при поиске потерянного КОНЕЦ в запросе на несколько сотен строк.
ПЗ
Практическое замечание

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

Итог

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

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

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

Можно ли вкладывать ВЫБОР КОГДА внутрь другого ВЫБОРА в запросе 1С?

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

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

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

Как отладить, в какую ветку попадает строка?

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

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

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

Что использовать вместо вложенного выбора, если правила часто меняются?

Вынесите соответствия в справочник или регистр сведений и соединяйтесь с ним в запросе. Тогда пользователи смогут менять правила классификации без доработки кода, а запрос останется простым.

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

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