При разработке сложных отчетов или формировании выборки данных в системе 1С:Предприятие, программисты часто сталкиваются с необходимостью фильтрации записей по временным интервалам или специфическим условиям, которые невозможно выразить стандартными операторами сравнения. Именно в таких ситуациях на сцену выходит мощный инструмент языка запросов — конструкция ВЫБОР КОГДА. Этот синтаксический элемент позволяет создавать гибкие условия фильтрации, аналогичные оператору CASE в стандартном SQL, но адаптированные под специфику платформы.

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

Синтаксическая структура и базовые принципы

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

Важно отметить, что система 1С последовательно проверяет каждое условие. Как только найдено первое истинное условие, соответствующее ему значение возвращается, и дальнейшая проверка прекращается. Это поведение необходимо учитывать при проектировании логики: более специфичные условия должны располагаться перед общими. Если ни одно из условий не выполнено, можно предусмотреть ветвь ИНАЧЕ, которая вернет значение по умолчанию, либо запрос вернет NULL.

Использование этой конструкции особенно актуально при работе с виртуальными таблицами, где условия часто передаются параметрами. Вы можете динамически менять логику выборки без переписывания всего текста запроса. Например, в зависимости от флага в параметре, запрос может выбирать данные за текущий месяц или за весь год, используя одну и ту же структуру ВЫБОР КОГДА в секции условий.

💡

Порядок условий имеет решающее значение для производительности. Размещайте самые частые и легко проверяемые условия (например, сравнение с константой) в начале списка, чтобы движок запросов мог быстрее отсечь лишние записи.

Работа с датами и временными интервалами

Одной из самых распространенных задач является фильтрация документов или регистров по периодам, границы которых могут быть плавающими. Стандартные операторы < или >= не всегда удобны, когда нужно выбрать данные "с начала квартала" или "за последние N дней". Здесь оператор ВЫБОР КОГДА в сочетании с функциями работы с датами становится незаменимым инструментом для разработчика.

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

При работе с типом ДатаВремя следует помнить о точности до секунды. Часто возникает ошибка, когда разработчик забывает, что конец дня — это не 23:59:59, а начало следующего дня. Использование ВЫБОР КОГДА позволяет корректно обрабатывать такие граничные случаи, явно указывая логику включения или исключения пограничных значений времени.

📊 Какой способ фильтрации по датам вы используете чаще?
Параметры в коде 1С
Виртуальные таблицы
Оператор ВЫБОР КОГДА
Функции начала/конца периода

Использование с типами значений и перечислениями

Платформа 1С поддерживает строгую типизацию, и часто в одной колонке таблицы могут храниться значения разных типов (например, в поле "Контрагент" может быть ссылка на организацию или на физическое лицо). Оператор ВЫБОР КОГДА позволяет элегантно решать задачи фильтрации по типу значения или по конкретному виду перечисления.

Вы можете проверять тип данных с помощью функции ТИПЗНАЧЕНИЯ или сравнивать значения перечислений напрямую. Это особенно полезно при формировании универсальных отчетов, где логика вывода зависит от вида объекта. Например, если тип значения — СправочникСсылка.Номенклатура, мы применяем одни условия отбора, если СправочникСсылка.Услуги — другие.

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

Тип условия Пример синтаксиса Описание логики
Сравнение дат КОГДА Дата < НАЧАЛОДНЯ(СЕГОДНЯ()) Отбор записей, дата которых строго меньше начала текущего дня.
Проверка типа КОГДА ТИПЗНАЧЕНИЯ(Поле) = ТИП("СправочникСсылка") Фильтрация строк, где поле содержит ссылку на объект справочника.
Перечисление КОГДА Статус = Перечисления.Статусы.Завершен Выбор записей с конкретным статусом из предопределенного списка.
Значение NULL КОГДА Поле ЕСТЬ NULL Обработка записей, где конкретное поле не заполнено.
💡

Оператор ВЫБОР КОГДА позволяет объединять условия разной природы (даты, типы, перечисления) в единую логическую цепочку, упрощая поддержку кода запроса.

Интеграция с виртуальными таблицами и параметрами

Виртуальные таблицы регистров накопления и срезов часто требуют передачи параметров для определения периода или состава измерений. Использование ВЫБОР КОГДА внутри параметров виртуальной таблицы позволяет динамически формировать эти условия. Это особенно актуально для отчетов типа "Оборотно-сальдовая ведомость", где пользователь может выбрать произвольный набор периодов.

При передаче параметров в виртуальную таблицу через конструкцию ПАРАМЕТРЫ, вы можете использовать результат работы ВЫБОР как значение параметра. Это дает возможность строить сложные зависимости: например, если выбран режим "По дням", параметр периода принимает значение дня, если "По месяцам" — значение месяца.

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

Особенности оптимизации

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

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

Разработчики часто допускают ошибку, пытаясь использовать ВЫБОР КОГДА там, где достаточно простого логического И или ИЛИ. Это усложняет чтение запроса и может негативно сказаться на скорости выполнения. Конструкция должна применяться именно тогда, когда требуется возврат разных значений или сложная ветвящаяся логика, которую трудно выразить линейно.

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

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

⚠️ Внимание: При использовании оператора ВЫБОР КОГДА внутри условий соединения таблиц (ЛЕВОЕ СОЕДИНЕНИЕ ... НА), убедитесь, что условия не дублируют логику фильтрации в секции ГДЕ. Это может привести к непредсказуемому количеству строк в результате (эффект декартова произведения).

☑️ Проверка корректности запроса

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

Примеры практического применения в коде

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

В следующем примере показано, как можно реализовать условный отбор в секции ГДЕ. Допустим, нам нужно выбрать товары, у которых остаток больше нуля, но только если это не группа товаров "Архив". Логика разветвляется в зависимости от значения реквизита "ВидНоменклатуры".

ВЫБРАТЬ

Номенклатура.Ссылка КАК Номенклатура,

ВЫБОР

КОГДА Номенклатура.Вид = &ВидАрхив

ТОГДА 0

ИНАЧЕ РегистрНакопления.Остатки.ОстатокКоличество

КОНЕЦ КАК Остаток

ИЗ

Справочник.Номенклатура КАК Номенклатура

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Остатки КАК РегистрНакопления

ПО Номенклатура.Ссылка = РегистрНакопления.Номенклатура

ГДЕ

ВЫБОР

КОГДА &ПоказыватьАрхив = ИСТИНА

ТОГДА ИСТИНА

ИНАЧЕ Номенклатура.Вид <> &ВидАрхив

КОНЕЦ

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

⚠️ Внимание: Интерфейс и возможности конструктора запросов могут различаться в разных версиях платформы 1С (8.2, 8.3, 8.3.20+). Некоторые сложные конструкции ВЫБОР КОГДА удобнее писать вручную в режиме текста, так как графический интерфейс может не поддерживать все варианты вложенности.

💡

Универсальность запроса, достигаемая через параметры и оператор ВЫБОР, снижает количество дублирующегося кода в модулях отчетов и упрощает тестирование.

Диагностика и отладка сложных условий

Когда запрос с использованием ВЫБОР КОГДА начинает работать некорректно или медленно, первым шагом должна стать проверка плана выполнения. В режиме отладки запросов 1С позволяет увидеть, как именно интерпретируются условия. Часто бывает видно, что сложная ветвь КОГДА вынуждает систему читать таблицу полностью, игнорируя индексы.

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

Используйте функцию ЕСТЬ NULL аккуратно. Пустые значения в 1С могут вести себя непредсказуемо в условиях сравнения. Явная проверка на NULL в отдельной ветке ВЫБОР КОГДА часто является лучшим решением, чем попытка обработать их в общей логике сравнения.

Можно ли вкладывать один ВЫБОР КОГДА внутрь другого?

Да, вложение конструкций ВЫБОР КОГДА друг в друга полностью поддерживается языком запросов 1С. Вы можете создать сколь угодно глубокую вложенность, однако следует помнить о читаемости кода. Если вложенность превышает 2-3 уровня, рекомендуется вынести часть логики в отдельные подзапросы или временные таблицы.

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

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

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

В таком случае оператор ВЫБОР вернет значение NULL (пустое значение). Это стандартное поведение для SQL-подобных языков. Если такое поведение нежелательно, всегда явно указывайте ветку ИНАЧЕ с дефолтным значением, например, 0 или пустой строкой.

Можно ли использовать ВЫБОР КОГДА в предложении УПОРЯДОЧИТЬ ПО?

Технически это возможно, но крайне не рекомендуется и часто приводит к ошибкам или непредсказуемой сортировке. Логика сортировки должна быть простой и однозначной. Если вам нужно сортировать по сложному правилу, лучше создать вычисляемое поле в списке выбора с помощью ВЫБОР, а затем сортировать по имени этого поля.