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

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

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

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

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

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

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

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

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

ВЫБОР

КОГДА <Условие1>

ТОГДА <Значение1>

КОГДА <Условие2>

ТОГДА <Значение2>

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

КОНЕЦ

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

Количество веток КОГДА не ограничено, но на практике конструкции длиннее 5–7 условий плохо читаются — их лучше заменить соединением со вспомогательной таблицей соответствий. Каждое условие — это логическое выражение: сравнение, проверка В ИЕРАРХИИ, ПОДОБНО, ЕСТЬ NULL и другие предикаты языка запросов.

Простой пример: перевод статуса в текст

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

ВЫБРАТЬ

Заказы.Номер,

ВЫБОР

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

ТОГДА "Оплачен"

КОГДА Заказы.Отгружен

ТОГДА "Отгружен без оплаты"

ИНАЧЕ "Ожидает оплаты"

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

ИЗ

Документ.ЗаказПокупателя КАК Заказы

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

Псевдоним КАК Статус обязателен, если поле будет использоваться в отчёте СКД или обращении к выборке по имени. Без псевдонима платформа сгенерирует служебное имя, к которому неудобно обращаться в коде.

Условия с диапазонами и вычислениями

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

ВЫБРАТЬ

Остатки.Номенклатура,

Остатки.КоличествоОстаток,

ВЫБОР

КОГДА Остатки.КоличествоОстаток <= 0

ТОГДА "Нет в наличии"

КОГДА Остатки.КоличествоОстаток < 10

ТОГДА "Заканчивается"

ИНАЧЕ "В наличии"

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

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

Здесь важно, что границы диапазонов не пересекаются «в лоб»: условие < 10 проверяется только после того, как не сработало <= 0. Это позволяет писать компактные цепочки без явного указания нижней границы каждого диапазона.

В ветках ТОГДА допустимы не только литералы, но и выражения: арифметика над полями, функции РАЗНОСТЬДАТ, НАЧАЛОПЕРИОДА, значения параметров запроса. Например, ТОГДА Продажи.Сумма * 0.95 — корректная ветка для расчёта суммы со скидкой.

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

ВЫБОР с NULL, соединениями и ссылочными типами

При левом соединении таблиц несовпавшие строки дают NULL в полях правой таблицы. ВЫБОР — стандартный способ подменить NULL осмысленным значением:

ВЫБОР

КОГДА Цены.Цена ЕСТЬ NULL

ТОГДА 0

ИНАЧЕ Цены.Цена

КОНЕЦ КАК Цена

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

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

ВЫБОР в итогах, группировках и СКД

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

СУММА(ВЫБОР

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

ТОГДА Продажи.Сумма

ИНАЧЕ 0

КОНЕЦ) КАК СуммаКрупныхПродаж

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

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

Чем заменить ВЫБОР в разных ситуациях

ЕСТЬNULL(Поле, Значение)

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

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

Лучше при большом числе вариантов: соответствия хранятся в данных, а не зашиты в текст запроса.

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

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

Постобработка в коде

Гибче всего, но медленнее: перебор выборки в цикле проигрывает вычислению на стороне СУБД.

Типичные ошибки и как их избежать

Первая и самая частая ошибка — пропущенное слово КОНЕЦ или ИНАЧЕ там, где оно нужно по логике. Без ИНАЧЕ запрос не упадёт, но вернёт NULL для всех строк, не попавших ни под одно условие, и это легко пропустить на тестовых данных, где все строки «удобные».

Вторая ошибка — неверный порядок условий. Если более общее условие стоит выше частного, частное никогда не сработает. Например, КОГДА Сумма > 0 перед КОГДА Сумма > 100000 «съест» все крупные документы в первой ветке.

Третья группа проблем — сравнение с NULL обычным равенством. Выражение КОГДА Поле = NULL всегда ложно: проверка на NULL выполняется только через ЕСТЬ NULL или НЕ ... ЕСТЬ NULL. Это поведение унаследовано из логики SQL и не является ошибкой платформы.

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

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

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

Контрольные точки: граничные значения диапазонов (ровно 0, ровно порог), NULL в исходных полях, пустые ссылки, строки с незаполненными реквизитами. Именно на границах чаще всего вскрываются ошибки в знаках сравнения — < вместо <= и наоборот.

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

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

Как проверить корректность ВЫБОР

Строка не попадает ни в одно условие
Норма

Возвращается значение из ИНАЧЕ

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

В поле NULL — ветка ИНАЧЕ отсутствует

Граничное значение диапазона
Норма

Попадает в ожидаемую категорию

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

Попадает в соседнюю — ошибка в знаке сравнения

NULL в исходном поле
Норма

Обрабатывается отдельной веткой ЕСТЬ NULL

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

Строка молча уходит в ИНАЧЕ или даёт NULL

Итоги по вычисляемому полю
Норма

Сходятся с ручным расчётом

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

Итоги занижены — NULL попал в агрегат

FAQ

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

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

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

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

Есть ли ограничение на количество веток КОГДА?

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

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

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

Работает ли ВЫБОР в динамических списках?

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

Почему запрос с ВЫБОР выдаёт ошибку «Несовместимые типы»?

Причина почти всегда в том, что разные ветки возвращают значения разных типов — например, строку и ссылку. Приведите ветки к одному типу: используйте ПРЕДСТАВЛЕНИЕ для ссылок, явные литералы нужного типа или функцию ВЫРАЗИТЬ.

Итог

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

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