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

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

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

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

Конструкция ВЫБОР КОГДА в языке запросов 1С 8 — это аналог оператора CASE из стандартного SQL. Она позволяет вернуть в поле запроса разные значения в зависимости от выполнения условий, не прибегая к постобработке результата кодом. Это один из самых востребованных приёмов при построении отчётов, динамических списков и выборок для обмена данными.

Типовая задача: нужно вывести в отчёте текстовый статус документа («Проведён», «Не проведён», «Помечен»), рассчитать категорию клиента по сумме продаж или подставить значение по умолчанию, когда реквизит не заполнен. Всё это решается одной конструкцией прямо в тексте запроса, что ускоряет выполнение и упрощает дальнейшую обработку.

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

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

Существует две формы записи. Первая — полная, с независимыми условиями в каждой ветке КОГДА. Вторая — сокращённая, когда сравнивается одно выражение с несколькими значениями. Обе формы завершаются ключевым словом КОНЕЦ, которое разработчики часто забывают, получая ошибку синтаксиса.

ВЫБОР

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

ТОГДА "Крупный клиент"

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

ТОГДА "Средний клиент"

ИНАЧЕ "Обычный клиент"

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

Сокращённая форма выглядит компактнее и читается легче, когда проверяется равенство одного поля конкретным значениям:

ВЫБОР Документ.ВидОперации

КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа)

ТОГДА "Реализация"

КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Возврат)

ТОГДА "Возврат от покупателя"

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

КОНЕЦ КАК ОписаниеОперации

Обратите внимание: в сокращённой форме возможна только проверка на равенство. Для диапазонов, неравенств, проверок на NULL и составных условий с И/ИЛИ используйте полную форму.

Типичные сценарии применения

Вывод текстового статуса вместо служебных признаков

Пользователю отчёта неудобно видеть булевы поля «Проведен» и «ПометкаУдаления». Конструкция ВЫБОР превращает их в понятный статус:

ВЫБОР

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

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

КОГДА Документ.Проведен

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

ИНАЧЕ "Не проведён"

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

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

Подстановка значения по умолчанию вместо NULL

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

ВЫБОР

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

ТОГДА "Нет на складе"

КОГДА Остатки.Количество < Номенклатура.МинимальныйОстаток

ТОГДА "Требуется заказ"

ИНАЧЕ "Достаточно"

КОНЕЦ КАК СостояниеЗапаса

Расчётные поля и группировка по категориям

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

Ограничения и требования к типам данных

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

Чтобы избежать усечения, приведите строковый результат к нужной длине явно с помощью ВЫРАЗИТЬ:

ВЫРАЗИТЬ(ВЫБОР

КОГДА Условие ТОГДА "Длинный текст статуса"

ИНАЧЕ "Короткий"

КОНЕЦ КАК СТРОКА(50)) КАК Статус

Вторая частая проблема — сравнение с NULL. Обычное равенство «Поле = NULL» никогда не истинно: в логике запросов NULL не равен ничему, включая сам себя. Для проверки используйте только конструкцию «Поле ЕСТЬ NULL».

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

Производительность и влияние на план запроса

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

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

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

ВЫБОР КОГДА в запросе

Подходит для простого ветвления по полям выборки; выполняется на СУБД, быстро, но ограничен логикой запроса.

ЕСТЬNULL

Подходит только для замены NULL значением по умолчанию; короче и читабельнее, но не умеет произвольных условий.

Временная таблица соответствий

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

Расчёт в коде после запроса

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

Пошаговый порядок написания конструкции

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

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

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

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

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

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

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

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

Все строки получили осмысленные значения из ТОГДА или ИНАЧЕ

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

Встречаются NULL — значит, нет ИНАЧЕ или типы несовместимы

Доля строк в ветке ИНАЧЕ
Норма

Небольшая, объяснимая доля нестандартных случаев

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

Большинство строк попало в ИНАЧЕ — условия не соответствуют данным

Строковые значения в отчёте
Норма

Текст выводится полностью, без обрезки

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

Значения усечены — нужно ВЫРАЗИТЬ к большей длине строки

Границы безопасной самостоятельной работы

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

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

Полезная привычка — писать ветку ИНАЧЕ не как «пустышку», а с диагностическим значением вроде «Не классифицировано». Тогда проблемные строки сразу видны в отчёте, а не теряются среди корректных данных, и пользователи сами сигнализируют о неучтённых случаях.
ПЗ
Практическое замечание

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

Чем ВЫБОР КОГДА отличается от ЕСТЬNULL?

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

Можно ли использовать ВЫБОР в секции ГДЕ?

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

Почему строковое значение в результате обрезалось?

Платформа определяет длину строки по значениям внутри конструкции и может усечь результат до минимальной. Решение — обернуть всю конструкцию в ВЫРАЗИТЬ(... КАК СТРОКА(N)) с достаточной длиной.

Работает ли ВЫБОР КОГДА в динамических списках форм?

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

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

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

Почему условие «Поле = NULL» внутри КОГДА не срабатывает?

В логике языка запросов NULL не равен никакому значению, включая NULL, поэтому сравнение всегда даёт ложь. Используйте конструкцию «Поле ЕСТЬ NULL» — только она корректно определяет отсутствие значения.

Итог

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

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