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