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

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

1С ВЫБОР КОГДА с двумя условиями: синтаксис и примеры

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

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

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

Синтаксис ВЫБОР КОГДА с двумя условиями

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

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

bsl
ВЫБОР
	КОГДА Продажи.Сумма >= 100000
		ТОГДА "Крупный заказ"
	КОГДА Продажи.Сумма >= 10000
		ТОГДА "Средний заказ"
	ИНАЧЕ "Мелкий заказ"
КОНЕЦ КАК КатегорияЗаказа

В примере выше два условия образуют три диапазона: от 100000, от 10000 до 100000 и всё остальное. Обратите внимание: второе условие не требует проверки «меньше 100000» — это уже гарантировано тем, что первая ветка не сработала.

Практический пример: классификация по двум критериям

Рассмотрим задачу из торгового учёта: нужно пометить строки табличной части реализации в зависимости от количества и цены. Запрос выбирает данные документа и добавляет вычисляемое поле с пояснением.

bsl
ВЫБРАТЬ
	РеализацияТовары.Номенклатура КАК Номенклатура,
	РеализацияТовары.Количество КАК Количество,
	РеализацияТовары.Цена КАК Цена,
	ВЫБОР
		КОГДА РеализацияТовары.Количество >= 100
			ТОГДА "Оптовая позиция"
		КОГДА РеализацияТовары.Цена > 50000
			ТОГДА "Дорогая позиция"
		ИНАЧЕ "Обычная позиция"
	КОНЕЦ КАК ТипПозиции
ИЗ
	Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары
ГДЕ
	РеализацияТовары.Ссылка = &Ссылка

Здесь два условия проверяют разные поля. Если строка подходит под оба критерия сразу, сработает первая ветка — «Оптовая позиция». Если нужно, чтобы приоритет был у цены, ветки меняют местами. Это и есть главный приём управления логикой: порядок КОГДА определяет приоритет.

Псевдоним после КОНЕЦ (КАК ТипПозиции) обязателен, если поле будет использоваться в коде через обращение по имени. Без псевдонима платформа присвоит служебное имя, и обращение к колонке выборки станет неудобным.

Два условия через И / ИЛИ в одной ветке

Иногда «два условия» означают не две ветки, а составное условие внутри одной КОГДА. Логические операторы И, ИЛИ, НЕ работают в условиях выбора так же, как в секции ГДЕ. Скобки задают приоритет вычисления.

bsl
ВЫБОР
	КОГДА Контрагенты.ЮрФизЛицо = &ЮрЛицо
		И Контрагенты.СтранаРегистрации = &Россия
		ТОГДА "Резидент"
	КОГДА Контрагенты.ЮрФизЛицо = &ФизЛицо
		ИЛИ Контрагенты.СтранаРегистрации <> &Россия
		ТОГДА "Особый контур"
	ИНАЧЕ "Прочие"
КОНЕЦ

Разница между двумя ветками и одной составной веткой принципиальна. Две ветки возвращают разные значения для разных ситуаций. Составное условие возвращает одно значение, но только когда выполнены оба требования (И) или хотя бы одно (ИЛИ). Выбирайте форму по смыслу результата, а не по количеству проверок.

Вложенный ВЫБОР: условие внутри условия

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

bsl
ВЫБОР
	КОГДА Контрагенты.ЮрФизЛицо = &ЮрЛицо
		ТОГДА ВЫБОР
			КОГДА Контрагенты.СтранаРегистрации = &Россия
				ТОГДА "Резидент"
			ИНАЧЕ "Нерезидент"
		КОНЕЦ
	ИНАЧЕ "Физическое лицо"
КОНЕЦ

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

Типы возвращаемых значений и NULL

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

Отдельная ловушка — NULL во входных данных. Сравнение с NULL всегда даёт не «истину» и не «ложь», а неопределённость, поэтому строка с NULL в проверяемом поле не попадёт ни в одну ветку КОГДА и уйдёт в ИНАЧЕ. Если это нежелательно, оберните поле в ЕСТЬNULL: например, ЕСТЬNULL(Таблица.Сумма, 0).

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

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

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

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

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

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

Количество строк в каждой категории
Норма

Все ожидаемые категории присутствуют в выборке

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

Одна из веток не вернула ни одной строки при наличии подходящих данных

Значения в колонке результата
Норма

Нет NULL, если ветка ИНАЧЕ задана

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

Встречаются NULL — условие не покрывает часть данных

Строки с пустыми исходными полями
Норма

Обработаны через ЕСТЬNULL и попали в нужную ветку

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

Молча ушли в ИНАЧЕ, искажая статистику

Альтернативы ВЫБОР КОГДА

Не каждую задачу стоит решать конструкцией выбора. Если значений много и они хранятся в данных (например, соответствие категорий и ставок), правильнее соединить таблицу со справочником или таблицей соответствий через ЛЕВОЕ СОЕДИНЕНИЕ. Это избавляет от правки запроса при добавлении новых значений.

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

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

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

Подходит для 2–5 фиксированных условий; работает в СКД и динамических списках; требует правки запроса при изменении логики

Соединение со справочником

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

Вычисление в коде после запроса

Подходит для разовой обработки в модуле; не работает в СКД и динамических списках

Итог

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

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

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

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

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

Сколько веток КОГДА можно добавить?

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

Почему в результате NULL, хотя ветка ИНАЧЕ есть?

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

Как сравнить поле с перечислением в условии?

Через оператор ЗНАЧЕНИЕ: КОГДА Документ.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа). Параметр запроса с нужным значением перечисления тоже подходит и удобнее, если значение может меняться.

Работает ли ВЫБОР КОГДА в СКД?

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