Разработка и Конфигурация · 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Определите, какое значение должно получиться в каждом случае, и перечислите все варианты входных данных
- 2Запишите ветки КОГДА от самого строгого условия к самому мягкому
- 3Добавьте ИНАЧЕ со значением по умолчанию, чтобы исключить NULL
- 4Убедитесь, что все ТОГДА и ИНАЧЕ возвращают значения одного типа
- 5Выполните запрос в консоли запросов и проверьте результат на граничных значениях
Ограничения и совместимость типов
Главное ограничение — все ветки ТОГДА и ИНАЧЕ должны возвращать значения совместимых типов. Если одна ветка возвращает строку, а другая — число, запрос либо не выполнится с ошибкой, либо поведение будет зависеть от СУБД. Для ссылочных типов тоже стоит быть аккуратным: смешение ссылок на разные виды документов в одном поле сделает его составным, что усложнит дальнейшую обработку и может замедлить соединения.
Строковые литералы в разных ветках должны иметь одинаковую длину или приводиться с помощью ВЫРАЗИТЬ(… КАК Строка(N)). Иначе при выгрузке в таблицу значений длина строки может быть усечена до длины первой ветки, и часть текста потеряется.
Ещё одно ограничение: в условиях КОГДА нельзя использовать агрегатные функции напрямую. Если условие зависит от суммы или количества, сначала выполните группировку во вложенном запросе, а затем применяйте ВЫБОР к уже рассчитанным итогам.
КОГДА против обработки результата в коде: что выбрать
Альтернатива КОГДА — выбрать исходные поля и выполнить ветвление в модуле на встроенном языке, обходя выборку. Такой подход оправдан, когда логика сложная: нужны вызовы функций общих модулей, обращение к нескольким объектам, нестандартные алгоритмы. Язык запросов не вызывает произвольный код, и попытка «втиснуть» сложную бизнес-логику в ВЫБОР делает запрос нечитаемым.
Однако для типовых преобразований — статусы, категории, подмена NULL, простые расчёты — вычисление в запросе эффективнее. Данные обрабатываются на сервере СУБД одним проходом, меньше объём передаваемых данных, а результат сразу пригоден для СКД, динамических списков и группировок. В динамических списках и отчётах на СКД обход в коде вообще недоступен, поэтому КОГДА там — единственный способ получить вычисляемое поле.
Сравнение вариантов
Подходит для статусов, категорий, подмены NULL, простых расчётов. Работает в СКД и динамических списках, быстрее на больших выборках. Ограничение — только декларативная логика.
Короткая замена для одного случая — подмены NULL значением по умолчанию. Не подходит, если для разных значений нужны разные результаты.
Подходит при сложной логике с вызовами функций и обращениями к объектам. Медленнее на больших данных и недоступен в динамических списках и СКД.
Как проверить, что КОГДА работает правильно
Перед переносом запроса в конфигурацию проверьте его в консоли запросов на реальных данных. Убедитесь, что в выборку попали строки для каждой ветки условия, включая граничные значения: ровно пороговая сумма, NULL в соединяемой таблице, пустая дата. Часто ошибка порядка условий видна только на границе диапазона.
Дополнительно полезно временно вывести рядом исходное поле и вычисляемое — так рассогласование заметно сразу. Если запрос используется в отчёте СКД, проверьте итоги по группировкам: NULL в вычисляемом поле образует отдельную группу с пустым представлением, что является верным признаком отсутствующего ИНАЧЕ.
Как проверить результат
Каждая строка получила осмысленное значение из ожидаемого списка
Встречаются NULL или пустые строки — не хватает ИНАЧЕ или не учтён NULL во входных данных
Сумма ровно на пороге попадает в нужную категорию
Пороговые строки попадают не в ту ветку — нарушен порядок условий
Один тип во всех строках, строки не обрезаны
Смешанные типы или усечённый текст — нужна унификация типов и ВЫРАЗИТЬ
Часто задаваемые вопросы
Можно ли использовать КОГДА без ВЫБОР и КОНЕЦ?
Нет. КОГДА — это не отдельная функция, а часть составного оператора. Минимальная корректная конструкция: ВЫБОР КОГДА условие ТОГДА значение ИНАЧЕ значение КОНЕЦ. Без обрамляющих ключевых слов запрос не пройдёт синтаксическую проверку.
Сколько веток КОГДА можно написать в одном операторе?
Явного жёсткого ограничения на количество веток нет. На практике при числе веток больше пяти-семи запрос становится трудно читать — в таких случаях лучше завести таблицу соответствия (например, регистр сведений) и соединиться с ней, чем разворачивать длинный ВЫБОР.
Можно ли вкладывать один ВЫБОР внутрь другого?
Да, вложенные конструкции ВЫБОР…КОНЕЦ допустимы и в ТОГДА, и в ИНАЧЕ. Это рабочий приём для двухуровневой классификации, но глубже одного уровня вложенности код становится плохо читаемым — рассмотрите соединение со справочной таблицей.
Работает ли КОГДА в динамических списках и СКД?
Да, оператор ВЫБОР полностью поддерживается в тексте запроса динамического списка и в наборах данных СКД. Более того, в СКД есть и собственная функция ВычислитьВыражение, но для простых условий достаточно КОГДА прямо в запросе набора данных.
Чем КОГДА отличается от функции ЕСТЬNULL?
ЕСТЬNULL решает одну задачу — подменяет NULL заданным значением. КОГДА универсальнее: позволяет проверять любые условия и возвращать разные значения для разных случаев. Если нужно только убрать NULL, пишите ЕСТЬNULL — это короче и понятнее.
Почему условие КОГДА Поле = 0 не ловит пустые остатки после левого соединения?
Потому что отсутствующая строка правой таблицы даёт NULL, а сравнение NULL с нулём не даёт ИСТИНУ. Замените условие на «Поле ЕСТЬ NULL» или оберните поле в ЕСТЬNULL(Поле, 0) до сравнения.
Что важно запомнить
КОГДА — ветка условного оператора ВЫБОР…КОНЕЦ в языке запросов 1С. Располагайте условия от строгого к мягкому, всегда добавляйте ИНАЧЕ, проверяйте NULL через ЕСТЬ NULL, приводите типы и длины строк во всех ветках к единому виду. Для простых преобразований вычисляйте поле в запросе, а сложную логику выносите в код.