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

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

ВЫБОР КОГДА ТОГДА в 1С: как строить условия в запросах

Разбираем конструкцию ВЫБОР КОГДА ТОГДА ИНАЧЕ КОНЕЦ в языке запросов 1С: синтаксис, примеры, типичные ошибки, сравнение с ЕСТЬNULL и практические сценарии.

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

Разработчики часто ищут эту тему по запросу «1с выбор когда тогда», когда нужно, например, вывести в отчёте слово «Просрочен» вместо даты или выбрать цену из разных источников. Ниже разобраны синтаксис, типовые сценарии, ограничения по типам данных и ошибки, которые приводят к неочевидным результатам.

Синтаксис конструкции ВЫБОР КОГДА ТОГДА

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

ВЫБОР

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

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

ИНАЧЕ "Мелкая"

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

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

Если ни одно условие не сработало и ветка ИНАЧЕ отсутствует, результат поля будет NULL. Это частая причина «пустых» значений в отчётах: разработчик забыл ИНАЧЕ, а часть строк не попала ни под одно условие.

Простой пример: подстановка текста по условию

Самая частая задача — заменить техническое значение на понятное пользователю. Например, вывести признак оплаты заказа:

ВЫБРАТЬ

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

ВЫБОР

КОГДА Заказ.Оплачен ТОГДА "Оплачен"

ИНАЧЕ "Не оплачен"

КОНЕЦ КАК СтатусОплаты

ИЗ

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

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

Обратите внимание: строковые литералы в запросе 1С пишутся в двойных кавычках. Если внутри строки нужны кавычки, их удваивают.

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

Конструкция удобна для разбиения числовых значений на диапазоны — например, ABC-анализа или категорий дебиторской задолженности по сроку:

ВЫБОР

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

ТОГДА "Свыше 90 дней"

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

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

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

КОНЕЦ КАК ГруппаПросрочки

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

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

Работа со ссылочными типами и NULL

Когда поле может быть не заполнено, простое сравнение не сработает: NULL = NULL даёт не ИСТИНА, а NULL. Поэтому проверку на пустоту внутри ВЫБОР делают через ЕСТЬ NULL или сравнение с пустой ссылкой:

ВЫБОР

КОГДА Реализация.Склад ЕСТЬ NULL ТОГДА "Склад не указан"

КОГДА Реализация.Склад = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка)

ТОГДА "Склад не указан"

ИНАЧЕ Реализация.Склад.Наименование

КОНЕЦ КАК Склад

Отдельная тонкость — составные поля. Если реквизит может хранить ссылки разных типов документов, внутри ВЫБОР удобно проверять тип через ВЫРАЗИТЬ или функцию ТИПЗНАЧЕНИЯ совместно с ТИП(), чтобы ветки возвращали однородный результат.

ВЫБОР против ЕСТЬNULL и ВЫРАЗИТЬ: что выбрать

Часть задач, которые новички решают через ВЫБОР, проще и быстрее выразить специализированными функциями. Сравнение вариантов:

ЗадачаПодходящий инструментПочему
Заменить NULL значением по умолчаниюЕСТЬNULL(Поле, 0)Короче и читаемее, чем ВЫБОР с проверкой ЕСТЬ NULL
Одно условие с двумя исходамиВЫБОР КОГДА … ИНАЧЕ … КОНЕЦСтандартное применение
Несколько диапазонов или условийВЫБОР с несколькими КОГДАЕдинственный способ задать цепочку условий
Приведение составного поля к одному типуВЫРАЗИТЬВЫБОР типы не приводит, только выбирает значения

Правило простое: если задача — «если пусто, подставь значение», берите ЕСТЬNULL. Если нужна настоящая развилка по бизнес-логике — ВЫБОР.

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

ВЫБОР КОГДА ТОГДА

Гибкая цепочка условий любой сложности; минус — громоздкий синтаксис и требование совместимости типов веток

ЕСТЬNULL

Только подмена NULL значением по умолчанию; зато одна функция вместо четырёх строк

Условие в коде после запроса

Подходит для сложной логики с обращением к функциям общих модулей; минус — лишний обход выборки и невозможность использовать в СКД и динамических списках

ВЫБОР в секциях ИМЕЮЩИЕ, СГРУППИРОВАТЬ ПО и соединениях

Конструкция работает не только в списке выборки. Её можно использовать в условиях соединений, в секции ИМЕЮЩИЕ и в группировках. Например, сгруппировать продажи по вычисляемой категории:

ВЫБРАТЬ

ВЫБОР

КОГДА Продажи.СуммаОборот > 50000 ТОГДА "Крупные"

ИНАЧЕ "Обычные"

КОНЕЦ КАК Категория,

СУММА(Продажи.СуммаОборот) КАК Итого

ИЗ

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

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

ВЫБОР

КОГДА Продажи.СуммаОборот > 50000 ТОГДА "Крупные"

ИНАЧЕ "Обычные"

КОНЕЦ

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

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

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

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

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

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

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

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

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

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

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

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

Граничные значения попадают в нужные группы

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

Строки с пороговыми значениями в соседней категории — ошибка в знаке сравнения или порядке веток

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

Однородный тип, совместимый с дальнейшим использованием

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

Составной или неожиданный тип — ветки возвращают разнородные значения

В СКД вычисляемые поля с ВЫБОР лучше задавать на уровне запроса набора данных, а не в вычисляемых полях схемы: запрос выполняется на сервере СУБД и обычно быстрее, чем вычисление выражений при формировании отчёта.
ПЗ
Практическое замечание

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

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

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

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

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

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

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

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

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

Чем ВЫБОР отличается от функции ЕСТЬNULL?

ЕСТЬNULL решает ровно одну задачу — подмену значения NULL на заданное. ВЫБОР — универсальный условный оператор с произвольным числом условий. Если нужно только заменить NULL, ЕСТЬNULL короче и понятнее; во всех остальных случаях используйте ВЫБОР.

Почему запрос с ВЫБОР выдаёт ошибку о несовместимости типов?

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

Итог

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

ВЫБОР КОГДА ТОГДА ИНАЧЕ КОНЕЦ — условный оператор запросов 1С с последовательной проверкой веток. Всегда добавляйте ИНАЧЕ, следите за порядком условий и совместимостью типов результата, а для простой подмены NULL используйте ЕСТЬNULL.