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