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