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