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

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

Функция КОГДА в языке запросов 1С: синтаксис, примеры и типичные ошибки

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

Функция КОГДА — это условный оператор языка запросов 1С, который позволяет вычислять значение поля в зависимости от выполнения условия прямо в тексте запроса. Она заменяет ветвление «если — иначе» внутри выборки: вместо постобработки результата в коде модуля вы получаете готовое вычисленное значение на стороне СУБД.

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

Типичные задачи, где КОГДА незаменима: подстановка текстового статуса вместо числового кода, расчёт скидки по диапазону суммы, замена NULL на значение по умолчанию, формирование признака «просрочено/не просрочено» по дате оплаты, группировка данных по вычисляемым категориям. Ниже разобраны синтаксис, практические примеры, ограничения и ошибки, которые чаще всего встречаются у начинающих разработчиков.

Синтаксис оператора ВЫБОР с ветками КОГДА

Базовая форма записи выглядит так:

ВЫБОР

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

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

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

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

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

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

Проверка условий идёт сверху вниз: как только очередное условие КОГДА вернуло ИСТИНА, соответствующее значение ТОГДА становится результатом, а остальные ветки не вычисляются. Поэтому порядок условий имеет значение — более строгие проверки ставьте выше. Если в примере поменять ветки местами, сумма 150 000 попадёт в категорию «Средняя», потому что условие «>= 10000» сработает раньше.

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

Как вычислить поле по условию: практические примеры

Подстановка текста вместо кода

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

ВЫБРАТЬ

Реализация.Номер,

ВЫБОР

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

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

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

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

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

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

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

Расчёт значения по диапазону

В условиях КОГДА допустимы сравнения, логические операции И, ИЛИ, НЕ, проверки В и МЕЖДУ. Это позволяет строить многоступенчатые расчёты, например процента скидки:

ВЫБОР

КОГДА Заказ.СуммаДокумента МЕЖДУ 50000 И 99999

ТОГДА Заказ.СуммаДокумента * 0.05

КОГДА Заказ.СуммаДокумента >= 100000

ТОГДА Заказ.СуммаДокумента * 0.1

ИНАЧЕ 0

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

Обратите внимание: в ТОГДА можно указывать не только литерал, но и выражение — арифметику над полями, обращение к функциям языка запросов, значения перечислений через ЗНАЧЕНИЕ().

Замена NULL и работа с пустыми значениями

При левом соединении таблиц поля правой таблицы могут содержать NULL. Сравнение NULL с чем-либо даёт не ИСТИНУ и не ЛОЖЬ, а неопределённость, поэтому обычное условие КОГДА Поле = 0 не сработает для NULL. Для таких случаев есть два подхода.

Первый — функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию), которая короче и читабельнее. Второй — явная проверка в КОГДА: «КОГДА Поле ЕСТЬ NULL ТОГДА …». Вариант с КОГДА удобен, когда для NULL и для конкретного значения нужны разные результаты, а не одна подмена:

ВЫБОР

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

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

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

ТОГДА "Закончился"

ИНАЧЕ "В наличии"

КОНЕЦ КАК НаличиеТовара

КОГДА в группировках, итогах и условиях ГДЕ

Результат ВЫБОР…КОНЕЦ можно использовать не только как выводимое поле, но и как поле группировки. Это удобно для сводной аналитики: например, сгруппировать продажи по категориям «крупная/средняя/мелкая» без создания дополнительного реквизита в документе. Поле с вычисляемым выражением просто перечисляется в секции СГРУППИРОВАТЬ ПО — либо само выражение, либо его псевдоним через обращение во вложенном запросе.

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

В секции ГДЕ сам оператор ВЫБОР использовать нельзя — там применяются обычные логические условия. Но можно отфильтровать данные по результату вычисляемого поля, если вынести его во вложенный запрос или временную таблицу и накладывать условие уже на него.

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

Ограничения и совместимость типов

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

Строковые литералы в разных ветках должны иметь одинаковую длину или приводиться с помощью ВЫРАЗИТЬ(… КАК Строка(N)). Иначе при выгрузке в таблицу значений длина строки может быть усечена до длины первой ветки, и часть текста потеряется.

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

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

КОГДА против обработки результата в коде: что выбрать

Альтернатива КОГДА — выбрать исходные поля и выполнить ветвление в модуле на встроенном языке, обходя выборку. Такой подход оправдан, когда логика сложная: нужны вызовы функций общих модулей, обращение к нескольким объектам, нестандартные алгоритмы. Язык запросов не вызывает произвольный код, и попытка «втиснуть» сложную бизнес-логику в ВЫБОР делает запрос нечитаемым.

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

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

КОГДА в запросе

Подходит для статусов, категорий, подмены NULL, простых расчётов. Работает в СКД и динамических списках, быстрее на больших выборках. Ограничение — только декларативная логика.

ЕСТЬNULL

Короткая замена для одного случая — подмены NULL значением по умолчанию. Не подходит, если для разных значений нужны разные результаты.

Обход результата в коде

Подходит при сложной логике с вызовами функций и обращениями к объектам. Медленнее на больших данных и недоступен в динамических списках и СКД.

Как проверить, что КОГДА работает правильно

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

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

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

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

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

Каждая строка получила осмысленное значение из ожидаемого списка

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

Встречаются NULL или пустые строки — не хватает ИНАЧЕ или не учтён NULL во входных данных

Граничные значения
Норма

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

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

Пороговые строки попадают не в ту ветку — нарушен порядок условий

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

Один тип во всех строках, строки не обрезаны

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

Смешанные типы или усечённый текст — нужна унификация типов и ВЫРАЗИТЬ

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

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

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

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

Явного жёсткого ограничения на количество веток нет. На практике при числе веток больше пяти-семи запрос становится трудно читать — в таких случаях лучше завести таблицу соответствия (например, регистр сведений) и соединиться с ней, чем разворачивать длинный ВЫБОР.

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

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

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

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

Чем КОГДА отличается от функции ЕСТЬNULL?

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

Почему условие КОГДА Поле = 0 не ловит пустые остатки после левого соединения?

Потому что отсутствующая строка правой таблицы даёт NULL, а сравнение NULL с нулём не даёт ИСТИНУ. Замените условие на «Поле ЕСТЬ NULL» или оберните поле в ЕСТЬNULL(Поле, 0) до сравнения.

Итог

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

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