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