Разработка эффективных отчетов и механизмов выборки данных в платформе 1С:Предприятие 8 невозможна без глубокого понимания логики условных переходов непосредственно внутри запроса. Хотя многие разработчики привыкли формировать результирующие наборы данных, а затем обрабатывать их циклами в коде на встроенном языке, такой подход часто приводит к снижению производительности при больших объемах информации.

Конструкция КОГДА (аналог CASE в SQL) позволяет выполнять ветвление логики прямо на уровне СУБД. Это дает возможность классифицировать записи, присваивать вычисляемые значения или формировать текстовые метки еще до того, как данные попадут в буфер приложения 1С.

Использование этого оператора требует внимания к синтаксису и пониманию того, как именно сервер баз данных интерпретирует условия. В этой статье мы разберем структуру оператора, рассмотрим типичные сценарии применения и обсудим нюансы, которые влияют на скорость выполнения запросов.

Синтаксическая структура оператора КОГДА

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

Базовая структура напоминает классический оператор if...else, но адаптирована под декларативный стиль SQL-подобных языков. Вы должны четко определить проверяемое выражение и результат, который будет возвращен при истинности условия.

Обратите внимание на обязательное завершение конструкции ключевым словом КОНЕЦ. Отсутствие этого маркера приведет к синтаксической ошибке при компиляции текста запроса.

⚠️ Внимание: В отличие от некоторых диалектов SQL, в 1С оператор КОГДА не поддерживает неявное опускание ключевого слова ТОГДА. Пропуск этого слова вызовет ошибку парсинга запроса.

Рассмотрим общий шаблон записи:

ВЫБРАТЬ

КОГДА Условие1 ТОГДА Результат1

КОГДА Условие2 ТОГДА Результат2

ИНАЧЕ РезультатПоУмолчанию

КОНЕЦ КАК ИмяПоля

ИЗ Таблица

Каждое условие проверяется последовательно. Как только найдено первое истинное выражение, соответствующий результат возвращается, и дальнейшая проверка прекращается. Это важно учитывать при оптимизации: более вероятные условия стоит размещать выше в списке.

Простые условия и проверка на NULL

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

Особого внимания заслуживает работа с пустыми значениями. В языке запросов 1С пустая ссылка и значение NULL (неопределенное значение) могут вести себя по-разному в зависимости от контекста, но оператор КОГДА позволяет явно обработать оба случая.

Вы можете комбинировать логические операторы И, ИЛИ внутри условия для создания сложных критериев отбора.

💡

Используйте функцию ЕСТЬNULL() внутри условия КОГДА, если вам нужно явно отличить пустую ссылку от значения NULL, хотя в большинстве случаев сравнение с NULL работает предсказуемо.

Пример классификации документов по сумме:

ВЫБРАТЬ

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

КОГДА ДокументРеализацияТоваровУслуг.Сумма > 100000 ТОГДА "Крупный опт"

КОГДА ДокументРеализацияТоваровУслуг.Сумма > 10000 ТОГДА "Мелкий опт"

ИНАЧЕ "Розница"

КОНЕЦ КАК КатегорияКлиента

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

В данном примере мы не просто фильтруем данные, а обогащаем их новой аналитической характеристикой. Это позволяет избежать последующего прохода по коллекции в цикле Для каждого.

Вложенные конструкции и сложная логика

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

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

Вложенные конструкции часто применяются при расчете коэффициентов или ставок, которые зависят от иерархии справочников или периодов действия регламентов.

  • 📊 Позволяет реализовать многофакторную классификацию без выхода в код 1С.
  • ⚡ Ускоряет формирование итоговых отчетов за счет обработки на стороне СУБД.
  • 🔍 Упрощает поддержку логики, так как все правила сбора данных находятся в одном месте.

Пример вложенной логики для расчета премии:

ВЫБРАТЬ

Сотрудник,

КОГДА Стаж > 5 ТОГДА

(КОГДА Выработка > 100 ТОГДА 1.5

ИНАЧЕ 1.2

КОНЕЦ)

ИНАЧЕ 1.0

КОНЕЦ КАК КоэффициентПремии

ИЗ РегистрСведений.ВыработкаСотрудников

Здесь внешний оператор проверяет стаж, а внутренний — выработку, но только для тех, кто работает более 5 лет. Для остальных сразу применяется коэффициент 1.0.

📊 Какой уровень вложенности КОГДА вы считаете допустимым?
1-2 уровня
3-4 уровня
Более 5 уровней
Только плоская структура

Использование в секции ГДЕ для фильтрации

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

Такой подход позволяет создавать универсальные запросы, которые адаптируются под контекст выполнения без необходимости строить разные тексты запросов программно.

Например, вы можете фильтровать записи по дате, но правило сравнения меняется в зависимости от типа документа.

Тип документа Условие фильтрации даты Результат КОГДА
Приходная накладная Дата >= НачалоПериода ИСТИНА
Расходная накладная Дата <= КонецПериода ИСТИНА
Акт сверки Дата В Границах(Начало; Конец) ИСТИНА

Реализация такой логики в секции ГДЕ выглядит следующим образом:

ГДЕ

КОГДА ВидДокумента = &Вид1 ТОГДА Дата >= &НачалоПериода

КОГДА ВидДокумента = &Вид2 ТОГДА Дата <= &КонецПериода

ИНАЧЕ ЛОЖЬ

КОНЕЦ

Использование ЛОЖЬ в ветке ИНАЧЕ гарантирует, что записи с неподходящим типом документа будут исключены из выборки, если для них не предусмотрено явного условия.

Работа с таблицами значений и типами данных

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

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

⚠️ Внимание: Если одна ветка возвращает Число, а другая Строку, результирующее поле может иметь составной тип, что иногда вызывает сложности при дальнейшей обработке в СКД или при выгрузке в файл.

Для работы с таблицами значений часто используется конструкция с псевдонимами полей.

Нюанс работы с NULL в Таблице значений

Если в колонке Таблицы значений хранится Неопределено, сравнение в условии КОГДА может вернуть ЛОЖЬ. Используйте конструкцию "ПОЛЕ ЕСТЬ NULL" для явной проверки.

Пример преобразования числовых кодов в текстовые описания:

ВЫБРАТЬ

ТаблицаЗначений.КодСтатьи,

КОГДА ТаблицаЗначений.СуммаПлан > ТаблицаЗначений.СуммаФакт ТОГДА "Перевыполнение"

КОГДА ТаблицаЗначений.СуммаПлан < ТаблицаЗначений.СуммаФакт ТОГДА "Недовыполнение"

ИНАЧЕ "План выполнен"

КОНЕЦ КАК СтатусВыполнения

ИЗ &ТаблицаПланФакт КАК ТаблицаЗначений

Такой подход делает исходные данные более читаемыми для конечного пользователя сразу на этапе получения выборки.

Оптимизация производительности запросов

Использование оператора КОГДА влияет на план выполнения запроса сервером баз данных. В большинстве случаев современные СУБД (MS SQL, PostgreSQL) эффективно оптимизируют такие конструкции, превращая их в условные переходы на уровне байт-кода.

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

Старайтесь размещать наиболее частые сценарии в начале списка условий. Хотя оптимизатор запросов может переупорядочить условия, явное указание приоритетов иногда помогает ему выбрать более эффективный путь.

  • 🚀 Избегайте вызова пользовательских функций внутри веток ТОГДА.
  • 🛑 Не используйте КОГДА для эмуляции соединений (JOIN), если это возможно сделать стандартными средствами.
  • 📉 Проверяйте план выполнения запроса через консоль запросов при работе с миллионами записей.

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

💡

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

Частые ошибки и способы их устранения

Разработчики часто сталкиваются с типичными ошибками при написании условных конструкций. Одна из самых распространенных — несоответствие типов возвращаемых значений в разных ветках.

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

Также стоит помнить о лимитах на длину текста запроса. Очень большие конструкции с десятками условий могут превысить допустимый размер пакета или усложнить отладку.

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

Для устранения ошибок используйте явное приведение типов с помощью функций ЕСТЬЧИСЛО, ЕСТЬДАТА или конструкторов типов, если логика позволяет.

☑️ Проверка запроса перед запуском

Выполнено: 0 / 4
Можно ли использовать оператор КОГДА в виртуальных таблах регистров?

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

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

В теории оптимизатор СУБД должен сам определять лучший порядок. На практике, размещение наиболее вероятных условий в начале списка может незначительно ускорить выполнение, но главное — избегать тяжелых вычислений внутри самих условий.

Что вернет запрос, если ни одно условие не выполнилось и нет ИНАЧЕ?

Если ветка ИНАЧЕ не указана и ни одно из условий КОГДА не истинно, оператор вернет значение NULL (Неопределено) для данной строки результата.

Допустимо ли использовать КОГДА в параметрах соединения (JOIN)?

Прямое использование в условии соединения (ЛЕВОЕ СОЕДИНЕНИЕ ... НА ... КОГДА) синтаксически возможно, но часто приводит к сложностям в чтении и отладке. Рекомендуется выносить такую логику в подзапрос или секцию ГДЕ.

Как отладить сложную конструкцию КОГДА?

Лучший способ — временно заменить сложную логику на вывод промежуточных значений (флагов 0 и 1) для каждого условия, чтобы понять, какая ветка срабатывает для конкретных записей.