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

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

КОГДА в условии запроса 1С 8: как писать выбор по условию

Как использовать КОГДА (CASE) в условии запроса 1С 8: синтаксис, примеры с ТОГДА и ИНАЧЕ, выбор в ГДЕ, типичные ошибки и проверка результата в консоли запросов.

Конструкция КОГДА в языке запросов 1С 8 — это аналог оператора CASE из SQL. Она позволяет вычислять значение поля по условию прямо внутри запроса, без построчной обработки результата в коде. Такой подход сокращает объём программного кода и ускоряет выборку, потому что вся логика выполняется на стороне СУБД.

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

Синтаксис конструкции КОГДА в запросе 1С

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

ВЫБРАТЬ

Номенклатура.Наименование,

КОГДА Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20)

ТОГДА "20%"

ИНАЧЕ "Без НДС"

КОНЕЦ КАК Ставка

ИЗ

Справочник.Номенклатура КАК Номенклатура

Допускается несколько ветвей КОГДА внутри одной конструкции — они проверяются последовательно сверху вниз, и срабатывает первая истинная. Это удобно для градаций: например, «до 100», «от 100 до 1000», «свыше 1000». Порядок условий имеет значение: более частные проверки должны стоять раньше общих.

Как использовать КОГДА в списке полей ВЫБРАТЬ

Самый частый сценарий — вычисляемая колонка. В отчёте по продажам можно вывести категорию суммы документа, не добавляя реквизит в конфигурацию. Полученному полю обязательно присваивается псевдоним через КАК, иначе обратиться к нему в выборке не получится.

ВЫБРАТЬ

Продажи.Номенклатура,

Продажи.СуммаОборот,

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

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

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

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

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

КОНЕЦ КАК КатегорияПродажи

ИЗ

РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Продажи

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

КОГДА в условии ГДЕ и в соединениях таблиц

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

ГДЕ

КОГДА Продажи.Скидка > 0

ТОГДА Продажи.Цена * (1 - Продажи.Скидка / 100)

ИНАЧЕ Продажи.Цена

КОНЕЦ > &ПорогЦены

В соединениях КОГДА помогает подставлять разные таблицы-источники в зависимости от типа записи. Однако злоупотреблять этим не стоит: условие соединения с КОГДА часто не позволяет СУБД использовать индексы, и запрос на больших таблицах замедляется. Если соединение строится по вычисляемому условию, проверьте план запроса и время выполнения на реальном объёме данных.

Замена NULL и работа с составными типами

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

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

ТОГДА 0

КОГДА Остатки.КоличествоОстаток < 0

ТОГДА 0

ИНАЧЕ Остатки.КоличествоОстаток

КОНЕЦ КАК ДоступныйОстаток

При составных типах полей возникает типичная ловушка: сравнение поля с конкретным значением перечисления вернёт ложь для записей, где хранится ссылка другого типа, даже если логически она «подходит». В таких случаях используют ВЫРАЗИТЬ для приведения типа внутри условия либо проверяют тип через ТИПЗНАЧЕНИЯ.

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

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

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

Для простых случаев есть компактные альтернативы. ЕСТЬNULL(Поле, Значение) заменяет пару «КОГДА Поле ЕСТЬ NULL ТОГДА Значение ИНАЧЕ Поле КОНЕЦ». Выбор между ними — вопрос читаемости: ЕСТЬNULL короче, КОГДА универсальнее.

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

КОГДА...ТОГДА...ИНАЧЕ...КОНЕЦ

Подходит для любых условий и градаций; минус — многословность и необходимость следить за типами ветвей

ЕСТЬNULL

Короткая замена NULL на значение по умолчанию; не умеет проверять произвольные условия

Обработка в коде после запроса

Гибкая логика на встроенном языке; минус — лишний обход выборки и рост нагрузки на клиент-серверное взаимодействие

Как проверить запрос с КОГДА перед использованием

Перед тем как встраивать запрос в отчёт или модуль, прогоните его в консоли запросов на тестовых данных. Проверьте три вещи: корректность псевдонима вычисляемого поля, отсутствие NULL там, где ожидалось значение по умолчанию, и тип результирующей колонки — особенно если ветви возвращают разные литералы.

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

Полезно сознательно включить в тестовый набор записи, не попадающие ни под одно условие, — так сразу видно поведение ветви ИНАЧЕ. Также проверьте запись с граничным значением (ровно 100, ровно 0), чтобы убедиться, что операторы сравнения (>, >=) выбраны правильно.

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

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

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

Каждая запись получила ожидаемое значение по своей ветви

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

Часть записей содержит NULL или значение из неверной ветви

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

Один тип во всех строках, совместимый с дальнейшим использованием

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

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

Время выполнения
Норма

Запрос отрабатывает за приемлемое время на реальном объёме

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

Резкое замедление при КОГДА в соединении или ГДЕ

Частые вопросы

Можно ли использовать КОГДА в секции ИТОГИ?

Напрямую в списке итоговых полей КОГДА не применяется, но можно вычислить поле с КОГДА в основной выборке и затем суммировать его через СУММА в ИТОГАХ. Это стандартный приём для раздельных итогов по категориям.

Чем КОГДА в запросе отличается от Если в модуле?

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

Почему запрос с КОГДА выдаёт ошибку о несовместимости типов?

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

Работает ли КОГДА в параметрах виртуальных таблиц?

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

Как сравнить результат КОГДА с пустой ссылкой?

Используйте ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка) в ветви ТОГДА или в сравнении. Проверка через ЕСТЬ NULL не сработает, потому что пустая ссылка — это не NULL, а вполне определённое значение.

Итог

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

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