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

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

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

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

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

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

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

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

Полная форма выражения выглядит так:

ВЫБОР

КОГДА Условие1 ТОГДА Значение1

КОГДА Условие2 ТОГДА Значение2

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

КОНЕЦ

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

Существует и сокращённая форма — простой CASE, где сравнивается одно выражение с набором значений:

ВЫБОР Товары.ЕдиницаИзмерения

КОГДА ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.Штука) ТОГДА "шт."

КОГДА ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.Килограмм) ТОГДА "кг"

ИНАЧЕ "ед."

КОНЕЦ

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

Базовые сценарии применения

Подстановка текстового представления

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

ВЫБРАТЬ

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

ВЫБОР

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

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

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

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

ИЗ

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

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

Расчёт значения по условию

ВЫБОР КОГДА удобен для арифметики с разными коэффициентами:

ВЫБОР

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

КОГДА Продажи.Сумма >= 50000 ТОГДА Продажи.Сумма * 0.98

ИНАЧЕ Продажи.Сумма

КОНЕЦ КАК СуммаСоСкидкой

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

Выбор реквизита по приоритету

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

ВЫБОР

КОГДА Контрагент.ФактическийАдрес <> "" ТОГДА Контрагент.ФактическийАдрес

КОГДА Контрагент.ЮридическийАдрес <> "" ТОГДА Контрагент.ЮридическийАдрес

ИНАЧЕ "Адрес не указан"

КОНЕЦ КАК АдресДляПечати

Для простой замены NULL короче использовать функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию), но ВЫБОР КОГДА нужен там, где условие сложнее, чем проверка на NULL.

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

ВЫБОР КОГДА в условиях и соединениях

Выражение допустимо не только в списке полей. В секции ГДЕ оно позволяет строить гибкие фильтры без параметров-флагов:

ГДЕ

ВЫБОР

КОГДА &ТолькоАктивные

ТОГДА НЕ Номенклатура.ПометкаУдаления

ИНАЧЕ ИСТИНА

КОНЕЦ

Такой приём заменяет динамическую сборку текста запроса строкой: один и тот же запрос работает в двух режимах в зависимости от параметра. Это безопаснее и удобнее, чем конкатенация текста запроса в коде.

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

Типизация результата и подводные камни

Совместимость типов ветвей

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

Если поле результата должно быть строго типизированным (например, для дальнейшего помещения во временную таблицу или в поле компоновки данных), явно приведите тип через ВЫРАЗИТЬ(... КАК Строка(100)) или гарантируйте одинаковый тип во всех ветвях.

Пропущенное ИНАЧЕ

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

Сравнение с NULL внутри условия

Классическая ловушка: КОГДА Поле = NULL никогда не истинно. В логике запросов сравнение с NULL даёт не ИСТИНА или ЛОЖЬ, а неопределённость. Проверять NULL нужно только через Поле ЕСТЬ NULL или Поле ЕСТЬ НЕ NULL.

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

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

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

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

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

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

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

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

Все строки содержат ожидаемые варианты, NULL появляется только там, где это задумано

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

Часть строк имеет NULL, хотя условия должны были их покрыть

Тип поля результата
Норма

Один тип во всех строках, отборы и сортировка в СКД работают корректно

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

Составной тип, отбор по полю в отчёте не находит значения

Покрытие условий
Норма

Для каждого реального значения исходных данных срабатывает осмысленная ветвь

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

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

Альтернативы и когда их выбрать

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

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

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

ВЫБОР КОГДА

Подходит для 2–7 условий на полях текущей выборки; выполняется на СУБД. Ограничение — требование совместимости типов и ухудшение читаемости при росте числа ветвей.

ЕСТЬNULL

Лучший вариант для единственной задачи — заменить NULL значением по умолчанию. Не умеет ничего другого.

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

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

Обработка в коде после запроса

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

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

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

Да, это рабочий приём: СУММА(ВЫБОР КОГДА ВидОперации = Продажа ТОГДА Сумма ИНАЧЕ 0 КОНЕЦ) позволяет посчитать в одном запросе несколько итогов по разным условиям без соединений и объединений.

Почему запрос с ВЫБОР КОГДА выдаёт ошибку о несовместимости типов?

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

Какое максимальное количество ветвей КОГДА допустимо?

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

Работает ли ВЫБОР КОГДА в запросах к виртуальным таблицам регистров?

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

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

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

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

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

Итог

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

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