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

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

Запрос 1С: ВЫБОР КОГДА с параметром — синтаксис и практические примеры

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

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

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

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

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

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

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

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

Как передать параметр в условие ВЫБОР КОГДА

Параметр в условии записывается с амперсандом и сравнивается с полем выборки или константой. Типичный пример — выбор цены в зависимости от переданного типа цен:

ВЫБОР

КОГДА Цены.ТипЦены = &ТипЦены

ТОГДА Цены.Цена

ИНАЧЕ 0

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

До выполнения запроса параметр обязательно устанавливается в коде модуля:

Запрос = Новый Запрос;

Запрос.Текст = "...";

Запрос.УстановитьПараметр("ТипЦены", ВыбранныйТипЦен);

Результат = Запрос.Выполнить();

Если параметр не установлен, платформа при выполнении выдаст ошибку вида «Параметр не установлен». Это критично при отладке: текст запроса может быть синтаксически верным, но без вызова УстановитьПараметр запрос не выполнится. Проверяйте, что каждый параметр, встречающийся в тексте (включая параметры внутри ВЫБОР КОГДА), установлен ровно один раз до вызова Выполнить() или Выгрузить().

Порядок действий
  1. 1
    Сформулируйте условие и определите, что будет параметром: значение сравнения или возвращаемый результат
  2. 2
    Впишите параметр в текст запроса через амперсанд внутри ВЫБОР КОГДА
  3. 3
    Перед выполнением вызовите Запрос.УстановитьПараметр с нужным значением
  4. 4
    Выполните запрос и проверьте результат на тестовых данных с разными значениями параметра
  5. 5
    Проверьте пограничные случаи: NULL в параметре, пустая ссылка, незаполненное поле

Параметр как возвращаемое значение

Параметр может стоять не только в условии, но и после ТОГДА или ИНАЧЕ — тогда он определяет, какое значение попадёт в поле результата. Классический сценарий — переключение валюты отчёта или знака суммы:

ВЫБОР

КОГДА &ВключатьНДС

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

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

КОНЕЦ КАК Сумма

Здесь параметр булево типа используется прямо как условие — это допустимо, потому что в языке запросов булево значение само является логическим выражением. Такой приём делает запрос компактнее, чем сравнение &ВключатьНДС = ИСТИНА, хотя оба варианта рабочие.

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

bsl
ВЫБОР
	КОГДА &Режим = "Сумма"
		ТОГДА ВЫРАЗИТЬ(Обороты.СуммаОборот КАК ЧИСЛО(15,2))
	ИНАЧЕ ВЫРАЗИТЬ(Обороты.КоличествоОборот КАК ЧИСЛО(15,2))
КОНЕЦ КАК Показатель

Отбор записей: параметр внутри ГДЕ совместно с ВЫБОР

Иногда требуется не вычислить поле, а отфильтровать строки по условию, которое само зависит от параметра. Например, показывать только проведённые документы, либо все, если пользователь снял флаг. Прямой способ — условие в ГДЕ с использованием параметра:

ГДЕ

ВЫБОР

КОГДА &ТолькоПроведенные

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

ИНАЧЕ ИСТИНА

КОНЕЦ

Тот же результат обычно записывают проще и читабельнее через логическое ИЛИ: ГДЕ (НЕ &ТолькоПроведенные ИЛИ Документ.Проведен). Оба варианта дают одинаковый результат, но вариант с ИЛИ легче отлаживать и он привычнее большинству разработчиков.

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

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

Параметр внутри ВЫБОР КОГДА

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

Условие через И/ИЛИ с параметром

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

Разные тексты запроса в коде

Максимальная производительность и простота каждого запроса. Минус — дублирование текста и усложнение сопровождения

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

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

Третья группа проблем связана с NULL. Если сравниваемое поле содержит NULL (например, из-за левого соединения), то условие Поле = &Параметр не выполнится даже при совпадающих значениях — любое сравнение с NULL даёт ложь. Используйте ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) перед сравнением.

Отдельно стоит упомянуть параметры типа «список значений» или массив: их нельзя сравнивать через равенство, только через оператор В (Поле В (&СписокЗначений)). Внутри ВЫБОР КОГДА такая проверка тоже работает, но сам параметр должен быть установлен именно как массив или список.

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

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

Быстрый способ проверить логику — консоль запросов: вставьте текст, задайте параметры вручную и выполните. Меняйте значение параметра и смотрите, как переключаются ветки ВЫБОР КОГДА. Это быстрее, чем отладка через точки останова в конфигураторе.

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

Если запрос используется в СКД, параметры задаются в настройках схемы компоновки, а не через УстановитьПараметр. Проверяйте, что параметр объявлен на закладке «Параметры» СКД, имеет правильный тип и доступен пользователю, если он должен задаваться в отчёте.

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

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

Значение поля с ВЫБОР КОГДА
Норма

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

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

Поле всегда содержит значение из ИНАЧЕ — условие не срабатывает

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

Один простой тип (число, строка, ссылка)

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

Составной тип или поле без типа — ветки возвращают разные типы

Количество строк
Норма

Совпадает с ожидаемым по отбору

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

Строк меньше — вероятно, NULL в сравниваемом поле без ЕСТЬNULL

Выполнение запроса
Норма

Запрос выполняется без ошибок при любых значениях параметра

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

Ошибка «параметр не установлен» или несовместимость типов

Когда ВЫБОР КОГДА с параметром не подходит

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

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

Наконец, если условие зависит от данных, которых нет в выборке (например, от настроек пользователя в регистре сведений), параметр — единственный правильный путь: передать значение извне проще и быстрее, чем соединяться с регистром внутри запроса.

Итог

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

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

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

Можно ли использовать параметр прямо как условие без сравнения?

Да, если параметр имеет булево тип. Запись КОГДА &Флаг ТОГДА ... корректна: булево значение само является логическим выражением. Убедитесь только, что в УстановитьПараметр передаётся именно Истина или Ложь, а не строка «Истина».

Почему условие с параметром не срабатывает, хотя значения совпадают?

Чаще всего причина в несовпадении типов (строка вместо ссылки) или в NULL в сравниваемом поле. Проверьте тип параметра в отладчике и оберните поле в ЕСТЬNULL. Также убедитесь, что параметр установлен до вызова Выполнить(), а не после.

Как передать в параметр список значений для проверки внутри ВЫБОР?

Передайте массив или список значений и используйте оператор В: КОГДА Поле В (&Список) ТОГДА .... Сравнение через равенство со списком не работает. Тип элементов списка должен совпадать с типом поля.

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

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

Что вернёт ВЫБОР КОГДА, если ни одно условие не выполнилось и ИНАЧЕ нет?

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

Что быстрее: один запрос с ВЫБОР КОГДА или два разных запроса?

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