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

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

Иначе и выбор в запросе 1С 8.3: как работает условная конструкция

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

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

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

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

Синтаксис конструкции ВЫБОР с веткой ИНАЧЕ

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

ВЫБОР

КОГДА Продажи.Сумма > 100000

ТОГДА "Крупная"

КОГДА Продажи.Сумма > 10000

ТОГДА "Средняя"

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

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

Правила, которые нужно держать в голове:

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

Что происходит, если опустить ИНАЧЕ

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

Особенно опасно это в трёх ситуациях:

  • результат используется в группировке — строки с NULL сворачиваются в отдельную группу, которую легко не заметить;
  • поле участвует в соединении — NULL никогда не равен NULL, поэтому соединение по такому полю «теряет» строки;
  • значение выгружается в таблицу значений и дальше сравнивается в коде — сравнение с NULL требует отдельной проверки.

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

Совместимость типов в ветках ТОГДА и ИНАЧЕ

Все значения, которые возвращают ветки ТОГДА и ИНАЧЕ, должны быть совместимы по типу. Если одна ветка возвращает строку, а другая — число, конструктор запроса может выдать ошибку ещё на этапе проверки текста, а при динамическом формировании запроса ошибка проявится в момент выполнения.

Типичная ошибка — смешение строк разной длины. Например, ТОГДА "Крупная" и ИНАЧЕ "Очень мелкая номенклатура": платформа приведёт результат к строке с максимальной длиной, но если далее это поле сравнивается со строковым литералом или попадает в поле с ограниченной длиной, возможны обрезки. Надёжнее явно приводить тип через ВЫРАЗИТЬ(... КАК Строка(50)).

Для ссылочных типов в ИНАЧЕ правильно подставлять пустую ссылку через значение: ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка). Если вместо этого написать ИНАЧЕ НЕОПРЕДЕЛЕНО или NULL, дальнейшие проверки типа Если ТипЗнч(Поле) = ... в коде начнут вести себя иначе, чем ожидается.

Практические примеры с ИНАЧЕ

Статус документа по признакам

Классическая задача — вывести текстовый статус в зависимости от состояния документа:

ВЫБОР

КОГДА Реализация.ПометкаУдаления

ТОГДА "Помечен на удаление"

КОГДА Реализация.Проведен

ТОГДА "Проведен"

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

КОНЕЦ КАК Статус

Порядок условий здесь важен: помеченный на удаление документ одновременно может быть и проведённым, поэтому более «сильное» условие ставится первым.

Расчёт скидки по диапазонам суммы

ВЫБОР

КОГДА Продажи.СуммаОборот >= 500000

ТОГДА Продажи.СуммаОборот * 0.1

КОГДА Продажи.СуммаОборот >= 100000

ТОГДА Продажи.СуммаОборот * 0.05

ИНАЧЕ 0

КОНЕЦ КАК СуммаСкидки

Обратите внимание: в ИНАЧЕ стоит число 0, а не строка, чтобы тип поля остался числовым и с ним можно было выполнять агрегатные функции СУММА, СРЕДНЕЕ.

Замена NULL при левом соединении

ВЫБОР часто используют вместе с ЕСТЬNULL при левых соединениях:

ВЫБОР

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

ТОГДА "Нет на складе"

КОГДА Остатки.КоличествоОстаток < Номенклатура.МинимальныйЗапас

ТОГДА "Заказать"

ИНАЧЕ "Достаточно"

КОНЕЦ КАК СостояниеЗапаса

Проверка ЕСТЬ NULL должна идти первой: сравнение NULL с числом вернёт NULL (не ИСТИНА), и без первой ветки строки без остатков «провалились» бы в ИНАЧЕ с неверным статусом.

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

Типичные ошибки при использовании ИНАЧЕ

Первая группа ошибок — синтаксические: пропущенное КОНЕЦ, лишняя запятая перед КОНЕЦ, отсутствие ТОГДА после условия. Они диагностируются платформой сразу, поэтому опасности не представляют.

Вторая группа — логические, их сложнее поймать:

  • пересекающиеся условия в неправильном порядке — срабатывает не та ветка, которую ожидали;
  • сравнение с NULL через = вместо ЕСТЬ NULL — условие никогда не выполняется, и всё уходит в ИНАЧЕ;
  • несовпадение типов между ветками — ошибка выполнения или неявное приведение;
  • ожидание, что ИНАЧЕ поймает NULL входного поля — не поймает: если само поле NULL, любое сравнение с ним даёт NULL, а не ИСТИНА.
Типичные ошибки
01
Нет ветки ИНАЧЕ — строки без совпадений получают NULL и искажают группировки и соединения.
02
Сравнение поля со значением, когда поле равно NULL: условие не срабатывает, строка уходит в ИНАЧЕ с неверным результатом. Решение — первая ветка с проверкой ЕСТЬ NULL или обёртка ЕСТЬNULL.
03
Разные типы в ТОГДА и ИНАЧЕ (строка и число) — ошибка выполнения запроса.
04
Условия в неверном порядке: общее условие стоит выше частного и перехватывает все строки.

Альтернативы конструкции ВЫБОР

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

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

Третий вариант — постобработка в коде: выбрать «сырые» данные и заполнить производную колонку при обходе выборки. Это оправдано, когда условие требует сложной логики, вызова функций общего модуля или обращения к данным, недоступным в запросе. Минус — потеря возможности группировать и фильтровать по этому полю на уровне запроса.

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

ВЫБОР в запросе

Подходит для 2–7 условий на основе полей запроса. Результат доступен для группировки, итогов и отборов СКД. Ограничение — логика зашита в текст запроса.

Соединение с таблицей соответствий

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

Постобработка в коде

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

Как проверить, что конструкция работает правильно

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

Полезно сгруппировать результат по вычисленному полю: КОЛИЧЕСТВО(*) по каждому значению покажет распределение. Если все строки попали в ветку ИНАЧЕ — почти наверняка условия не выполняются из-за NULL или несовпадения типов сравниваемых значений.

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

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

Значения вычисленного поля
Норма

Присутствуют значения из разных веток, включая осмысленное значение ИНАЧЕ

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

Все строки содержат только значение ИНАЧЕ или NULL

Группировка по полю
Норма

Количество групп соответствует числу ожидаемых категорий

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

Появилась отдельная группа с пустым (NULL) значением

Итоги по числовым полям
Норма

Суммы совпадают с контрольными данными

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

Часть строк выпала из итогов после добавления ВЫБОР в соединение

Границы применимости и производительность

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

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

Маршрут решения

Как выбрать действие

Нужно 2–5 вариантов значения по полям текущего запросаИспользуйте ВЫБОР с явной веткой ИНАЧЕ
Правила соответствия задают пользователи и они часто меняютсяВынесите соответствие в регистр сведений и соединяйтесь с ним
Результат ВЫБОР внезапно везде равен значению ИНАЧЕПроверьте поля условий на NULL и добавьте первой веткой проверку ЕСТЬ NULL
Условие требует вызова функции или сложной бизнес-логикиВычисляйте поле при обходе результата в коде, а не в запросе

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

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

Нет, синтаксически она необязательна. Но без неё строки, не попавшие ни в одно условие КОГДА, получат значение NULL, что часто ломает группировки, соединения и дальнейшие сравнения. Рекомендуется писать ИНАЧЕ всегда, кроме случаев, когда NULL нужен осознанно.

Можно ли в ИНАЧЕ использовать другое поле таблицы?

Да, ветка ИНАЧЕ может содержать любое выражение: поле, арифметику, функцию языка запросов. Например, ИНАЧЕ Продажи.Сумма вернёт исходное значение поля, если ни одно условие не сработало. Главное — совместимость типа с остальными ветками.

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

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

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

Да, вложенные конструкции допустимы и в ТОГДА, и в ИНАЧЕ. Практический предел — один-два уровня вложенности: дальше запрос становится трудно читать и отлаживать, и лучше разбить логику на временные таблицы или перенести её в код.

Что вернёт ВЫБОР, если несколько условий КОГДА истинны одновременно?

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

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

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

Итог

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

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