Система компоновки данных (СКД) в 1С:Предприятие — мощный инструмент для создания гибких отчётов, но её синтаксис часто вызывает вопросы у разработчиков. Одна из самых востребованных конструкций — ВыборКогда Тогда Иначе — позволяет реализовать условную логику прямо в выражениях СКД. Однако при работе с несколькими условиями даже опытные программисты сталкиваются с нюансами: как правильно сгруппировать условия, избежать ошибок приоритета, или оптимизировать производительность?

В этой статье мы разберём не только базовый синтаксис, но и скрытые возможности конструкции, которые редко документируются. Например, как использовать вложенные ВыборКогда для многоуровневой логики, или почему иногда проще заменить их на Выразить() с параметрами. Особое внимание уделим типичным ошибкам, из-за которых отчёт либо выдаёт некорректные данные, либо работает слишком медленно на больших объёмах.

Материал будет полезен как начинающим разработчикам, которые только осваивают СКД, так и тем, кто хочет углубить свои знания. Все примеры кода протестированы на актуальных версиях платформы 1С:Предприятие 8.3 (включая 8.3.23).

Базовый синтаксис ВыборКогда Тогда Иначе в СКД

Конструкция ВыборКогда Тогда Иначе в 1С СКД аналогична оператору CASE WHEN в SQL или switch-case в языках программирования. Она позволяет возвращать разные значения в зависимости от выполнения условий. Общий вид:

ВыборКогда Условие1 Тогда Значение1

ИначеКогда Условие2 Тогда Значение2

...

Иначе ЗначениеПоУмолчанию

Конец

Ключевые особенности:

  • 🔹 Порядок условий важен: проверка идёт сверху вниз, и при первом совпадении возвращается соответствующее значение.
  • 🔹 Иначе — необязательный блок. Если его нет и ни одно условие не выполнилось, результат будет Неопределено.
  • 🔹 Внутри условий можно использовать любые выражения СКД, включая функции (НачалоПериода(), ВРег()) и поля наборов данных.

Пример простого использования для категоризации клиентов по сумме заказов:

ВыборКогда СуммаЗаказов > 1000000 Тогда "VIP"

ИначеКогда СуммаЗаказов > 100000 Тогда "Премиум"

Иначе "Стандарт"

Конец

💡

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

Работа с несколькими условиями: приоритеты и группировка

Когда условий становится больше трёх, возникает риск неявных ошибок приоритета. Например, если не учесть порядок проверок, клиент с суммой заказов 1 050 000 может попасть в категорию "Премиум" вместо "VIP". Чтобы избежать этого:

  1. Располагайте условия от наиболее специфичных к общим. Например, сначала проверяйте точные совпадения, затем диапазоны.
  2. Используйте Скобки() для явной группировки сложных выражений:
    ВыборКогда (СуммаЗаказов > 1000000 И Регион = "Москва") Тогда "VIP Москва"
    

    ИначеКогда СуммаЗаказов > 1000000 Тогда "VIP Регион"

    Иначе "Прочие"

    Конец

Обратите внимание: в отличие от SQL, где CASE WHEN допускает использование BETWEEN, в СКД придётся разбивать диапазоны на два условия с >= и <=.

📊 Как часто вы используете ВыборКогда в отчётах 1С?
Постоянно
Иногда
Редеко
Никогда

Вложенные ВыборКогда: когда это оправдано

Вложенные конструкции ВыборКогда позволяют реализовать многоуровневую логику, но чреваты двумя проблемами:

  1. Снижение читаемости — уже на третьем уровне вложенности код становится трудным для поддержки.
  2. Производительность — каждое условие проверяется последовательно, что может замедлить отчёт на больших данных.

Пример вложенного ВыборКогда для анализа продаж по сезонам и регионам:

ВыборКогда Месяц = 1 Тогда

ВыборКогда Регион = "Сибирь" Тогда "Зима. Сибирь"

Иначе "Зима. Прочие"

Конец

ИначеКогда Месяц = 7 Тогда "Лето"

Иначе "Межсезонье"

Конец

Альтернатива вложенным ВыборКогда

Часто проще вынести сложную логику в отдельную функцию на встроенном языке и вызвать её через Выразить(). Например:

Выразить("ОтчётыКлиентСервер.ПолучитьКатегориюКлиента(СуммаЗаказов, Регион)")

Это упростит поддержку и ускорит выполнение.

⚠️ Внимание: если вложенные условия используют одни и те же поля (например, СуммаЗаказов), СКД может дублировать запросы к базе. В этом случае лучше оптимизировать запрос на уровне источника данных.

Типичные ошибки и как их избежать

Даже опытные разработчики допускают ошибки при работе с ВыборКогда. Вот наиболее распространённые:

ОшибкаПричинаКак исправить
Не возвращается значение по умолчанию Отсутствует блок Иначе, а ни одно условие не выполнилось Добавьте Иначе Неопределено или явное значение
Некорректная сортировка результатов Условия проверяются не в том порядке (например, диапазон "100-500" идёт после "100-1000") Переставьте условия от наиболее узких к широким
Ошибка "Недопустимый тип операнда" Сравниваются несовместимые типы (например, строка с числом) Используйте функции приведения типа: Число(), Строка()

Ещё одна распространённая проблема — избыточные вычисления. Если в условии используется сложная функция (например, ВычислитьВыражение()), она будет выполняться каждый раз при проверке. Решение: вынесите результат во временное поле набора данных.

☑️ Проверка корректности ВыборКогда

Выполнено: 0 / 4

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

Конструкция ВыборКогда может значительно замедлить отчёт, если:

  • 🐢 В условиях используются Подзапросы() или агрегатные функции (Сумма(), Максимум()).
  • 🐢 Поля из условий не индексированы в базе данных.
  • 🐢 Логика дублируется в нескольких вычисляемых полях.

Рекомендации по оптимизации:

  1. Перенесите сложные условия в источник данных (например, в запрос или временную таблицу).
  2. Используйте ИндексироватьПо для полей, участвующих в условиях.
  3. Замените многократные ВыборКогда на одно поле с Выразить(), если логика повторяется.

Пример оптимизации: вместо

ВыборКогда СуммаЗаказов > 1000000 Тогда "VIP"

ИначеКогда КоличествоЗаказов > 50 Тогда "Активный"

Иначе "Стандарт"

Конец

лучше добавить вычисляемое поле в запрос:

ВЫБРАТЬ

Клиент,

ВыборКогда СуммаЗаказов > 1000000 Тогда "VIP"

ИначеКогда КоличествоЗаказов > 50 Тогда "Активный"

Иначе "Стандарт"

Конец КАК КатегорияКлиента

ИЗ ...

Альтернативы ВыборКогда: когда стоит использовать другие подходы

Не всегда ВыборКогда — оптимальное решение. Рассмотрим альтернативы:

  • 🔧 Выразить() — если логика слишком сложна для СКД или требует вызова внешних функций:
    Выразить("ОтчётыКлиентСервер.ОпределитьСтатусЗаказа(Дата, Сумма)")
  • 🔧 Временные таблицы — для категоризации больших наборов данных (например, распределение клиентов по сегментам).
  • 🔧 Параметры отчёта — если условия зависят от пользовательского ввода (например, пороговые значения для категорий).

⚠️ Внимание: если вам приходится писать более 10 условий в одном ВыборКогда, это признак того, что логику лучше вынести в отдельный алгоритм. В противном случае отчёт станет трудно поддерживать.

💡

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

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

Разберём реальные кейсы, где ВыборКогда с несколькими условиями решает типовые задачи:

  1. Сегментация клиентов по RFM-аналитике (Recency, Frequency, Monetary):
    ВыборКогда ДниСПоследнегоЗаказа < 30 И СуммаЗаказов > 50000 Тогда "Чемпионы"
    

    ИначеКогда ДниСПоследнегоЗаказа < 90 И КоличествоЗаказов > 10 Тогда "Лояльные"

    ИначеКогда СуммаЗаказов > 10000 Тогда "Перспективные"

    Иначе "Новые"

    Конец

  2. Анализ продаж по дням недели с учётом праздников:
    ВыборКогда Праздник = Истина Тогда "Праздник"
    

    ИначеКогда ДеньНедели(Дата) = 6 Тогда "Суббота"

    ИначеКогда ДеньНедели(Дата) = 7 Тогда "Воскресенье"

    Иначе "Будний день"

    Конец

  3. Контроль сроков оплаты:
    ВыборКогда ДниПросрочки > 30 Тогда "Критическая просрочка"
    

    ИначеКогда ДниПросрочки > 14 Тогда "Значительная просрочка"

    ИначеКогда ДниПросрочки > 0 Тогда "Небольшая просрочка"

    Иначе "Оплачено вовремя"

    Конец

Обратите внимание на использование ДеньНедели() и других встроенных функций СКД — они позволяют избежать ручного кодирования дат.

FAQ: Ответы на частые вопросы

Можно ли использовать ВыборКогда в параметрах отчёта?

Нет, конструкция ВыборКогда работает только в выражениях СКД (вычисляемые поля, отборы, условное оформление). Для параметров используйте Условие() на встроенном языке или создайте обработку с динамическим формированием схемы компоновки.

Как отладить ошибки в ВыборКогда?

Используйте пошаговую отладку:

  1. Проверьте каждое условие отдельно через Сообщить() в выражении.
  2. Упростите конструкцию, оставив только 2-3 условия, затем постепенно добавляйте остальные.
  3. Используйте ТрассировкаСКД() для анализа Generated SQL-запроса.

Почему ВыборКогда медленно работает на больших данных?

СКД преобразует условия в SQL-запрос, и если они содержат неоптимизированные функции (например, Найти() по строковым полям), это может тормозить выполнение. Решения:

  • Добавьте индексы на поля, используемые в условиях.
  • Перенесите логику в запрос (используйте ВЫБРАТЬ ВЫБОР КОГДА... в тексте запроса).
  • Разбейте отчёт на несколько более простых.

Можно ли в ВыборКогда использовать данные из других наборов?

Да, но с оговорками:

  • Если наборы связаны отношением "один ко многим", используйте агрегатные функции (Сумма(), Максимум()).
  • Для сложных связей лучше создать ОбъединениеДанных в схеме компоновки.
  • Избегайте Подзапросы() внутри ВыборКогда — это сильно замедляет работу.

Как заменить ВыборКогда на Выразить()?

Если логика слишком сложна для СКД, перенесите её в модуль отчёта:

Выразить("ОтчётыСервер.ОпределитьСтатусЗаказа(

Параметры.ДатаОтчёта,

Поля.СуммаДокумента,

Поля.ДатаОплаты

)")

Преимущества:

  • Легче отлаживать (можно использовать точку останова).
  • Можно использовать полный синтаксис , включая циклы и обработку исключений.
  • Код хранится в одном месте, что упрощает поддержку.