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