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

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

Как работает ВЫБОР в запросе 1С: синтаксис, примеры и типичные ошибки

Как работает конструкция ВЫБОР в запросе 1С: синтаксис, примеры с условиями, сравнение с ЕСТЬNULL, типичные ошибки и проверка результата в консоли запросов.

Конструкция ВЫБОР в языке запросов 1С — это аналог оператора CASE в SQL. Она позволяет прямо в тексте запроса проверять условия и возвращать разные значения в зависимости от данных, без постобработки результата в коде. Это один из самых востребованных приёмов при разработке отчётов, динамических списков и выборок для обменов.

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

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

Синтаксис конструкции ВЫБОР и порядок вычисления

Полная форма конструкции выглядит так:

ВЫБОР

КОГДА Условие1 ТОГДА Значение1

КОГДА Условие2 ТОГДА Значение2

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

КОНЕЦ

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

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

Базовый пример: замена ссылки на понятный текст

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

ВЫБРАТЬ

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

ВЫБОР

КОГДА Заказы.Проведен ТОГДА "Проведён"

КОГДА Заказы.ПометкаУдаления ТОГДА "Помечен на удаление"

ИНАЧЕ "Черновик"

КОНЕЦ КАК СостояниеДокумента

ИЗ

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

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

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

ВЫБОР с несколькими условиями и диапазонами

В условиях КОГДА допустимы любые логические выражения: сравнения, И/ИЛИ, проверки на NULL, функции языка запросов. Это позволяет строить классификации по диапазонам, например градацию дебиторской задолженности по сроку:

ВЫБОР

КОГДА РАЗНОСТЬДАТ(Долг.ДатаВозникновения, &ТекущаяДата, ДЕНЬ) > 90

ТОГДА "Более 90 дней"

КОГДА РАЗНОСТЬДАТ(Долг.ДатаВозникновения, &ТекущаяДата, ДЕНЬ) > 30

ТОГДА "31–90 дней"

ИНАЧЕ "До 30 дней"

КОНЕЦ КАК ВозрастДолга

Здесь критичен порядок условий: сначала проверяется самый строгий критерий. Если поменять ветки местами и поставить условие «более 30 дней» первым, все долги старше 90 дней попадут в него, и до проверки «более 90 дней» дело не дойдёт. При проектировании цепочки условий располагайте их от узких к широким.

Внутри условий можно ссылаться на параметры запроса (&Параметр), вложенные запросы и поля соединённых таблиц. Это делает ВЫБОР полноценным инструментом бизнес-логики на уровне выборки данных.

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

Обработка NULL: ВЫБОР против ЕСТЬNULL

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

ВЫБОР

КОГДА Остатки.Количество ЕСТЬ NULL ТОГДА 0

ИНАЧЕ Остатки.Количество

КОНЕЦ КАК Остаток

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

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

ВЫБОР или ЕСТЬNULL

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

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

ВЫБОР с проверкой ЕСТЬ NULL

Подходит, когда NULL — лишь одно из нескольких условий. Длиннее, но гибче: можно комбинировать проверки и возвращать разные значения.

ВЫБОР в условиях, группировках и итогах

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

ВЫБРАТЬ

ВЫБОР

КОГДА Продажи.Сумма >= 100000 ТОГДА "Крупная"

ИНАЧЕ "Обычная"

КОНЕЦ КАК КатегорияСделки,

СУММА(Продажи.Сумма) КАК СуммаПродаж

ИЗ

РегистрНакопления.Продажи.Обороты КАК Продажи

СГРУППИРОВАТЬ ПО

ВЫБОР

КОГДА Продажи.Сумма >= 100000 ТОГДА "Крупная"

ИНАЧЕ "Обычная"

КОНЕЦ

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

В СКД вычисляемые поля на основе ВЫБОР часто удобнее выносить на закладку «Вычисляемые поля» с выражением на языке запросов — тогда логика доступна для настройки пользователем без правки текста запроса.

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

Типичные ошибки и ограничения

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

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

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

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

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

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

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

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

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

Значения вычисляемой колонки
Норма

Во всех строках заполненные значения ожидаемого типа

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

Встречаются NULL или пустые значения — нет ветки ИНАЧЕ

Распределение по категориям
Норма

Каждая категория содержит ожидаемое число записей

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

Одна категория поглотила остальные — неверный порядок условий

Граничные значения
Норма

Значение ровно на границе попадает в задуманную категорию

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

Граница попадает не туда — проверьте знаки сравнения

Итог

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

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

Часто задаваемые вопросы

Чем ВЫБОР в запросе отличается от Если...Тогда в коде 1С?

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

Что вернёт ВЫБОР, если не указать ИНАЧЕ и ни одно условие не сработает?

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

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

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

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

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

Почему условие КОГДА Поле = &Параметр не срабатывает, хотя значения визуально совпадают?

Наиболее вероятная причина — поле содержит NULL, а NULL не равен никакому значению. Вторая причина — различие типов: например, строка сравнивается с числом или ссылка разных видов документов. Проверьте поле на ЕСТЬ NULL и убедитесь, что типы сравниваемых значений совпадают.

Что быстрее: ВЫБОР или соединение со справочником расшифровок?

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