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

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

Конструкция «КОГДА … ТОГДА» в запросе 1С: как писать условную логику

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

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

Такая конструкция незаменима, когда нужно классифицировать данные на лету: подставить текстовый статус вместо числового кода, рассчитать цену по разным правилам для разных групп товаров, заменить NULL на значение по умолчанию или развести суммы по колонкам дебета и кредита. При этом вся логика выполняется на стороне СУБД, без выгрузки данных в память и построчного обхода.

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

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

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

ВЫБОР

КОГДА Продажи.Количество >= 100

ТОГДА "Крупный заказ"

КОГДА Продажи.Количество >= 10

ТОГДА "Средний заказ"

ИНАЧЕ "Мелкий заказ"

КОНЕЦ КАК КатегорияЗаказа

Важно понимать порядок вычисления: условия проверяются сверху вниз, и срабатывает первая истинная ветка. Если в примере выше поменять ветки местами, все заказы с количеством от 10 попадут в «Средний заказ», потому что условие >= 10 выполнится раньше, чем >= 100. Порядок веток — часть логики, а не оформления.

Конструкцию можно использовать в списке выбираемых полей, в условии ГДЕ (через вложенный запрос или сравнение результата), в итогах, в полях компоновки данных и в выражениях СКД. Псевдоним после КОНЕЦ задаётся стандартно — через КАК ИмяПоля.

Типовые сценарии применения

Замена кода на читаемое представление

Самая частая задача — превратить служебные значения (числовые коды, ссылки на перечисления, булевы флаги) в понятный текст прямо в выборке. Например, для видов операций или состояний документа, чтобы отчёт сразу показывал «Проведён», «Отменён», «Черновик» вместо цифр.

Замена NULL значением по умолчанию

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

Разнесение сумм по колонкам

Классический приём в отчётах: одна таблица движений раскладывается на несколько колонок. Например, ВЫБОР КОГДА ВидДвижения = "Приход" ТОГДА Сумма ИНАЧЕ 0 КОНЕЦ КАК Приход и зеркальное выражение для расхода. Затем по этим полям строятся итоги через СУММА.

Условный расчёт цены или скидки

Когда правило расчёта зависит от категории клиента, объёма или периода, вся логика описывается ветками КОГДА. Это быстрее, чем выгружать данные и считать в цикле, и позволяет использовать результат в СКД без дополнительного кода.

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

Вложенные условия и несколько веток КОГДА

Количество веток КОГДА не ограничено практически, но с ростом их числа запрос становится трудно читать. Если условий больше пяти-семи, стоит подумать о том, чтобы вынести классификацию в справочник или регистр сведений и получать значение соединением — так логику смогут менять пользователи без правки запроса.

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

В условиях КОГДА можно использовать параметры запроса (&Параметр), функции работы с датами (НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, РАЗНОСТЬДАТ), проверки В ИЕРАРХИИ и ссылки на перечисления через ЗНАЧЕНИЕ(Перечисление.Имя.Значение). Это покрывает практически все прикладные сценарии без вложенности.

Ограничения по типам данных

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

Отдельный подводный камень — ссылочные типы. Если в разных ветках возвращаются ссылки на разные справочники (например, контрагент из одной ветки и склад из другой), поле станет составного типа. Для СКД и дальнейших соединений это допустимо, но усложняет обработку результата. Для строк помните про длину: строковые литералы разной длины могут привести к усечению при объединении с другими полями.

Чтобы гарантировать нужный тип, используйте явное приведение через ВЫРАЗИТЬ(... КАК ЧИСЛО(15,2)) или строковые литералы одинаковой длины. Это особенно важно, когда результат конструкции участвует в объединении запросов (ОБЪЕДИНИТЬ ВСЕ), где типы колонок должны совпадать строго.

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

Производительность и альтернативы

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

Альтернативы, которые стоит рассмотреть: функция ЕСТЬNULL для простой замены NULL; соединение со справочником классификаторов вместо длинного списка веток; расчёт в коде после выборки, если логика требует обращения к функциям встроенного языка, недоступным в запросе; вычисляемые поля СКД, если условие нужно только для отображения в отчёте.

Критерий выбора простой: если правило классификации часто меняется пользователями — выносите его в данные (справочник, регистр). Если это жёсткая алгоритмическая логика — оставляйте в запросе. Если значение нужно только визуально — считайте его в СКД или при выводе.

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

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

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

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

Перед тем как встраивать конструкцию в рабочий запрос, проверьте её в консоли запросов на реальных данных. Выведите рядом исходное поле и вычисляемое — так сразу видно, какие строки попали не в ту ветку. Особое внимание уделите граничным значениям: ровно 100 при условии «>= 100», пустые ссылки, NULL после соединений.

Если результат используется в итогах, сверьте суммы с контрольным расчётом по исходным данным. Классическая ошибка — строки с NULL в вычисляемом поле выпадают из группировки или попадают в отдельную группу с пустым значением, и итог «сходится, но не полностью».

При подозрении на неправильную классификацию временно добавьте в выборку номер сработавшей ветки: в каждой ветке ТОГДА возвращайте не только значение, но и маркер (1, 2, 3) в отдельное поле. После отладки маркер убирается.

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

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

Граничные значения условий
Норма

Записи на границе попадают в ожидаемую ветку

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

Часть записей уходит в ИНАЧЕ или соседнюю ветку

Поля без NULL
Норма

В вычисляемом поле нет пустых/NULL значений

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

Есть NULL — значит, не сработала ни одна ветка и нет ИНАЧЕ

Итоги по полю
Норма

Сумма итогов по категориям равна общей сумме

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

Итог меньше — часть строк потерялась из-за NULL или фильтра

Тип поля в результате
Норма

Один ожидаемый тип у всех строк

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

Составной тип или ошибка приведения типов

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

Можно ли использовать КОГДА без ВЫБОР в запросе 1С?

Нет. Ключевые слова КОГДА и ТОГДА существуют только внутри конструкции ВЫБОР … КОНЕЦ. Отдельного оператора КОГДА в языке запросов нет, в отличие от встроенного языка, где используется ЕСЛИ … ТОГДА.

Сколько веток КОГДА можно написать в одной конструкции?

Жёсткого ограничения платформа не накладывает, но при большом числе веток запрос становится трудно сопровождать. Ориентир: до пяти-семи условий — нормально, больше — рассмотрите вынос классификации в данные и соединение таблиц.

Почему условие «Поле = NULL» никогда не срабатывает?

Потому что NULL нельзя сравнивать оператором равенства — результат такого сравнения неопределён, а не истина. Используйте конструкцию «Поле ЕСТЬ NULL» или функцию ЕСТЬNULL для замены.

Можно ли в ТОГДА вернуть результат другого запроса?

Напрямую вставить вложенный запрос в ветку ТОГДА нельзя. Обходной путь — поместить нужные данные во временную таблицу, соединить её с основной выборкой и в ТОГДА использовать поле из соединения.

Что быстрее: ВЫБОР в запросе или ЕСЛИ при обходе выборки?

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

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

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

Итог

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

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