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