Разработка и Конфигурация · 9 мин
Оператор КОГДА в языке запросов 1С: как строить условия в запросах
Разбираем оператор КОГДА в языке запросов 1С: синтаксис ВЫБОР КОГДА ТОГДА ИНАЧЕ КОНЕЦ, примеры, типичные ошибки и ограничения при работе с условиями.
Оператор КОГДА в языке запросов 1С — это часть конструкции условного выбора, аналог CASE в классическом SQL. Она позволяет вернуть разные значения поля в зависимости от выполнения условий прямо в тексте запроса, без постобработки результата в коде. Это один из самых востребованных приёмов при построении отчётов, динамических списков и выборок для обмена данными.
Конструкция полностью называется «ВЫБОР … КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ» (в английском синтаксисе — CASE WHEN THEN ELSE END). Слово КОГДА открывает очередную ветку условия, и веток может быть сколько угодно. Запрос проверяет условия сверху вниз и возвращает значение из первой сработавшей ветки.
Практическая ценность оператора в том, что логика классификации данных переносится на сервер СУБД: меньше кода на встроенном языке, быстрее выполнение, проще поддержка. Ниже разберём синтаксис, типовые сценарии, ограничения и ошибки, которые чаще всего встречаются у начинающих разработчиков.
Синтаксис конструкции ВЫБОР … КОГДА … ТОГДА
Полная форма оператора выглядит так:
ВЫБОР
КОГДА Продажи.Сумма > 100000
ТОГДА "Крупная"
КОГДА Продажи.Сумма > 10000
ТОГДА "Средняя"
ИНАЧЕ "Мелкая"
КОНЕЦ КАК КатегорияСделки
Обязательные элементы — ВЫБОР, хотя бы одна пара КОГДА/ТОГДА и завершающее слово КОНЕЦ. Ветка ИНАЧЕ опциональна: если её опустить и ни одно условие не выполнится, поле получит значение NULL. Это частая причина «пустых» значений в отчётах, когда разработчик забыл про непокрытые случаи.
После КОНЕЦ принято сразу указывать псевдоним поля через КАК — без псевдонима обратиться к результату в коде или в настройках СКД будет затруднительно.
Какие условия допустимы после КОГДА
После КОГДА можно использовать любое логическое выражение, допустимое в секции ГДЕ: сравнения полей с константами и параметрами, проверки В ИЕРАРХИИ, В, МЕЖДУ, ПОДОБНО, ЕСТЬ NULL, а также логические связки И, ИЛИ, НЕ со скобками. Это делает оператор гибким инструментом классификации.
ВЫБОР
КОГДА Номенклатура.ВидНоменклатуры В (&ВидыУслуг)
ТОГДА "Услуга"
КОГДА Номенклатура.СрокГодности ЕСТЬ NULL
ТОГДА "Без срока годности"
КОГДА Номенклатура.СрокГодности МЕЖДУ &Начало И &Конец
ТОГДА "Истекает скоро"
ИНАЧЕ "Обычный товар"
КОНЕЦ КАК Категория
Важно помнить про порядок проверки: условия вычисляются последовательно, и первое выполнившееся «перехватывает» строку. Поэтому более частные условия ставят выше, а более общие — ниже. Если перепутать порядок, часть строк попадёт не в ту ветку, и запрос формально останется корректным — ошибку заметят только по неверным цифрам в отчёте.
Где применять оператор КОГДА на практике
Наиболее частые сценарии использования условного выбора в запросах:
- классификация строк отчёта по диапазонам сумм, дат, количества;
- замена кодов и перечислений на читаемые строковые представления;
- вычисление «знака» суммы: приход минус расход в одном поле;
- подмена NULL безопасным значением (альтернатива ЕСТЬNULL с логикой);
- условное соединение: выбор источника цены в зависимости от типа цен;
- построение полей-признаков для группировок и итогов в СКД.
Характерный пример — сворачивание прихода и расхода в одну колонку с нужным знаком:
ВЫБРАТЬ
Остатки.Номенклатура,
СУММА(ВЫБОР
КОГДА Остатки.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
ТОГДА Остатки.Количество
ИНАЧЕ -Остатки.Количество
КОНЕЦ) КАК Остаток
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Остатки
СГРУППИРОВАТЬ ПО
Остатки.Номенклатура
Такой приём позволяет получить агрегат за один проход по таблице, без разворачивания результата в коде. В регистрах накопления с готовыми итогами он не нужен, но при выборке из таблицы движений или чужих источников данных — стандартное решение.
Если ВЫБОР используется внутри агрегатной функции (СУММА, МАКСИМУМ), проверяйте, что во всех ветках возвращается числовой тип. Смешение числа и NULL в группировке даёт корректный результат, а вот смешение числа и строки приведёт к ошибке выполнения запроса.
Ограничения и подводные камни
Первое ограничение — типы результата. Все ветки ТОГДА и ИНАЧЕ должны возвращать совместимые типы. Если одна ветка возвращает строку, а другая — число, запрос либо не выполнится, либо приведёт типы непредсказуемым образом. Для ссылочных типов допустим составной результат, но с ним аккуратнее работать в СКД и при выгрузке.
Второй момент — производительность. ВЫБОР в списке полей вычисляется построчно и обычно дёшев, но если условие КОГДА содержит вложенный подзапрос или обращение через разыменование к нескольким таблицам, стоимость запроса заметно растёт. В таких случаях лучше сначала собрать нужные поля соединениями во временную таблицу, а условный выбор применить уже к плоским данным.
Третий нюанс — NULL в условиях. Сравнение поля, содержащего NULL, с любым значением даёт «не истину», поэтому строка уйдёт в ИНАЧЕ или вовсе не попадёт ни в одну ветку. Если NULL для поля возможен, добавляйте явную ветку КОГДА Поле ЕСТЬ NULL или оборачивайте поле в ЕСТЬNULL до сравнения.
Типичные ошибки при работе с КОГДА
Отдельно стоит сказать про сравнение строк: оператор «=» в запросах 1С для строк работает без учёта регистра на большинстве СУБД, но ПОДОБНО с шаблоном может вести себя иначе. Если классификация строится по текстовым признакам, проверяйте поведение на реальных данных, а не только на тестовом примере из двух строк.
Альтернативы оператору ВЫБОР
Не каждую задачу нужно решать через ВЫБОР. Если требуется просто заменить NULL значением по умолчанию, короче и читабельнее функция ЕСТЬNULL(Поле, Значение). Если нужна классификация по постоянному списку соответствий — надёжнее соединение с регистром сведений или таблицей значений, переданной как параметр.
Для сложной многоуровневой логики, где условия зависят от настроек пользователя, иногда проще получить «сырые» поля запросом и доклассифицировать строки в коде или в вычисляемых полях СКД. Вычисляемые поля СКД, кстати, поддерживают похожий синтаксис ВЫБОР и позволяют вынести оформительскую логику из запроса в настройки отчёта.
Сравнение вариантов
Подходит для классификации на лету и вычислений в агрегатах; ограничение — логика зашита в текст запроса.
Короткая замена NULL значением по умолчанию; не умеет ничего, кроме подмены NULL.
Для изменяемых соответствий, которые настраивает пользователь; требует дополнительной таблицы и индексов.
Для оформительской логики отчёта; не подходит, если результат нужен вне СКД.
Как проверить корректность запроса с условиями
После написания запроса с ВЫБОР полезно пройти короткий цикл проверки: выполнить запрос в консоли запросов на копии базы, убедиться, что каждая ветка реально срабатывает хотя бы на одной строке, и сверить количество строк в каждой категории с ожиданиями. Ветка, которая никогда не срабатывает на реальных данных, — признак ошибки в условии или в порядке проверок.
Как проверить результат
Каждая ветка КОГДА покрывает хотя бы одну строку тестовых данных
Ветка пустая на всех данных — вероятно, условие недостижимо
Сумма строк по всем категориям равна общему числу строк выборки
Часть строк ушла в NULL или неучтённую категорию
Во всех ветках один и тот же тип значения
Смешанные типы, ошибка выполнения или неожиданное приведение
Что важно запомнить
КОГДА работает только внутри ВЫБОР … КОНЕЦ, ветки проверяются сверху вниз, типы результатов должны совпадать, а ветка ИНАЧЕ и обработка NULL защищают от «потерянных» строк в отчётах.
Частые вопросы об операторе КОГДА
Можно ли использовать КОГДА без слова ВЫБОР?
Нет. КОГДА существует только внутри конструкции ВЫБОР … КОНЕЦ. Отдельного оператора КОГДА в языке запросов 1С нет — в отличие, например, от секции ГДЕ, которая является самостоятельной частью запроса.
Сколько веток КОГДА допустимо в одном ВЫБОР?
Формального жёсткого ограничения нет, но на практике больше 5–7 веток — признак того, что соответствие лучше вынести в регистр сведений и получать соединением. Длинные ВЫБОР трудно читать и поддерживать.
Чем отличается ВЫБОР в запросе от ЕСТЬNULL?
ЕСТЬNULL решает одну задачу — подмену NULL указанным значением. ВЫБОР — универсальный условный оператор с произвольными условиями. Если нужна только защита от NULL, используйте ЕСТЬNULL: запись короче и понятнее.
Работает ли ВЫБОР в секции ГДЕ и в итогах?
В секции ГДЕ ВЫБОР использовать не нужно — там условия записываются напрямую логическими выражениями. В группировках и итогах ВЫБОР применяется внутри агрегатных функций (например, СУММА(ВЫБОР … КОНЕЦ)) и как поле группировки — это типовой приём для сводных отчётов.
Можно ли в ТОГДА вернуть результат другого запроса?
Возвращать можно выражения над полями, параметрами и константами; вложенные скалярные подзапросы в этой позиции не поддерживаются. Если значение нужно вычислить отдельным запросом, передайте его параметром или соедините с заранее подготовленной временной таблицей.
Почему строка попала в ИНАЧЕ, хотя условие визуально верное?
Чаще всего причина в NULL в сравниваемом поле: любое сравнение с NULL не даёт истины. Проверьте поле на NULL, добавьте ветку КОГДА Поле ЕСТЬ NULL или оберните поле в ЕСТЬNULL перед сравнением. Вторая частая причина — более общее условие выше по списку перехватило строку раньше.