Работа с данными в системе 1С:Предприятие 8 часто требует не просто выборки информации, а её трансформации «на лету». Стандартный язык запросов платформы предоставляет мощный инструментарий для решения таких задач, и одним из ключевых элементов логики является оператор КОГДА ТОГДА ИНАЧЕ. Конструкция позволяет реализовывать условную логику непосредственно на стороне СУБД, что существенно повышает производительность по сравнению с обработкой результатов в коде 1С.
Использование этого оператора аналогично функции IIF или конструкции switch-case в других языках программирования. Вы можете динамически менять значения полей, присваивать новые метки или рассчитывать показатели в зависимости от условий, заданных в теле запроса. Понимание синтаксиса и особенностей вложенности критически важно для написания эффективных отчетов и обработок.
В данной статье мы подробно разберем синтаксис, рассмотрим реальные примеры использования от простых проверок на пустоту до сложных каскадных условий. Также уделим внимание типичным ошибкам и нюансам работы с типами данных, чтобы ваши запросы работали стабильно и быстро.
Базовый синтаксис и структура оператора
Любое условное выражение в языке запросов 1С начинается с ключевого слова КОГДА. За ним следует логическое условие, которое возвращает булево значение (Истина или Ложь). Если условие выполняется, управление передается блоку ТОГДА, где указывается значение, которое должно быть возвращено в результирующую выборку.
Если первое условие не выполнено, система проверяет следующие условия (если они есть) или переходит к блоку ИНАЧЕ. Блок ИНАЧЕ является опциональным, но его наличие гарантирует, что поле не примет значение NULL (Неопределено) при невыполнении всех предыдущих условий. Завершается вся конструкция ключевым словом КОНЕЦ.
Обратите внимание на порядок следования ключевых слов — это строгий синтаксический шаблон, нарушение которого приведет к ошибке компиляции запроса. Рассмотрим базовую структуру:
ВЫБРАТЬ
КОГДА Условие1 ТОГДА Значение1
КОГДА Условие2 ТОГДА Значение2
ИНАЧЕ ЗначениеПоУмолчанию
КОНЕЦ КАК НовоеПоле
ИЗ Таблица
⚠️ Внимание: Оператор КОГДА внутри конструкции может повторяться многократно, создавая цепочку проверок. Однако блок ИНАЧЕ может быть указан только один раз в конце всей ветви условий перед словом КОНЕЦ.
Простые условия: проверка на неопределенность и значения
Наиболее частый сценарий использования — проверка реквизитов справочников или документов на заполненность. В 1С пустое значение ссылочного типа часто представляется как NULL (Неопределено). С помощью нашего оператора можно подменять такие значения на понятные пользователю строки, например, «Не указан» или «Без контрагента».
Также конструкция позволяет сравнивать числовые и строковые значения. Вы можете присваивать разные категории товаров в зависимости от их артикула или менять статус документа based on его признака проведения.
Пример замены пустого значения ссылочного типа:
ВЫБРАТЬ
Номенклатура.Наименование,
КОГДА Номенклатура.Родитель = ЗНАЧЕНИЕ(Справочник.НоменклатурныеГруппы.ПустаяСсылка)
ТОГДА "Основная группа"
ИНАЧЕ Номенклатура.Родитель.Наименование
КОНЕЦ КАК ГруппаТовара
ИЗ
Справочник.Номенклатура КАК Номенклатура
В данном примере мы проверяем поле Родитель. Если оно пустое (равно пустой ссылке), то в колонку ГруппаТовара попадет строка «Основная группа». В противном случае система возьмет наименование реального родителя.
Для проверки на пустое значение в запросах 1С часто используют сравнение с ЗНАЧЕНИЕ(Тип.ПустаяСсылка) или оператор ЕСТЬ NULL. Выбор зависит от конкретной задачи и типа данных.
Вложенные условия и каскадная логика
Мощь оператора раскрывается при необходимости проверки нескольких условий последовательно. Вы можете вкладывать одну конструкцию КОГДА внутрь другой, создавая сложные деревья решений. Это позволяет классифицировать данные по множеству критериев в одном проходе по таблице.
При каскадной проверке условия оцениваются сверху вниз. Как только найдено первое истинное условие, соответствующее значение возвращается, и дальнейшая проверка прекращается. Это важно учитывать при оптимизации: более вероятные условия стоит ставить выше в списке.
Пример сложной классификации контрагентов:
- 🔵 Если контрагент является юридическим лицом, присваиваем тип «ЮЛ».
- 🟢 Если контрагент — физическое лицо, проверяем статус ИП.
- 🟠 Если статус ИП активен, пишем «ИП», иначе «Физлицо».
- ⚪ Во всех остальных случаях ставим прочерк.
ВЫБРАТЬ
Контрагенты.Наименование,
КОГДА Контрагенты.ЭтоЮридическоеЛицо = ИСТИНА ТОГДА "ЮЛ"
КОГДА Контрагенты.ЭтоФизическоеЛицо = ИСТИНА ТОГДА
КОГДА Контрагенты.ЭтоИндивидуальныйПредприниматель = ИСТИНА
ТОГДА "ИП"
ИНАЧЕ "Физлицо"
КОНЕЦ
ИНАЧЕ "-"
КОНЕЦ КАК ТипКонтрагента
ИЗ
Справочник.Контрагенты КАК Контрагенты
Такой подход позволяет избежать создания временных таблиц для промежуточных вычислений. Вся логика упакована в одно выражение, что делает код запроса компактным, хотя и требует внимательности при чтении из-за вложенности.
Вычисления и математические операции в условиях
В блоках ТОГДА и ИНАЧЕ можно размещать не только константы или поля, но и полноценные математические выражения. Это широко используется для расчета скидок, наценок или коэффициентов в зависимости от объема партии или категории клиента.
Система 1С автоматически приводит типы данных, если это возможно. Однако при смешивании разных типов (например, числа и строки) в одной колонке результата может возникнуть ошибка или непредсказуемое поведение. Рекомендуется явно приводить типы или следить за тем, чтобы все ветви возвращали данные одного типа.
Рассмотрим пример расчета итоговой суммы со скидкой:
| Условие (Сумма заказа) | Действие (Расчет) | Результат |
|---|---|---|
| Меньше 10 000 | Сумма * 1.0 | Без скидки |
| От 10 000 до 50 000 | Сумма * 0.95 | Скидка 5% |
| Более 50 000 | Сумма * 0.90 | Скидка 10% |
Реализация этого алгоритма в запросе выглядит следующим образом:
ВЫБРАТЬ
РеализацияТоваровУслуг.Сумма,
КОГДА РеализацияТоваровУслуг.Сумма < 10000 ТОГДА РеализацияТоваровУслуг.Сумма
КОГДА РеализацияТоваровУслуг.СумМА >= 10000 И РеализацияТоваровУслуг.Сумма <= 50000
ТОГДА РеализацияТоваровУслуг.Сумма * 0.95
ИНАЧЕ РеализацияТоваровУслуг.Сумма * 0.90
КОНЕЦ КАК СуммаСоСкидкой
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
⚠️ Внимание: При выполнении математических операций убедитесь, что поля не содержат значений
NULL. Операция с неопределенным значением вернетNULL, что может исказить итоги отчета. Используйте функциюЕСТЬ NULLдля предварительной фильтрации.
Работа с датами и временными интервалами
Частой задачей является группировка или маркировка данных по периодам. Оператор КОГДА отлично справляется с проверкой дат. Вы можете определять квартал, полугодие или относить документ к определенному отчетному периоду прямо в запросе.
При работе с датами важно учитывать точность сравнения. Если поле содержит время, а вы сравниваете только дату, используйте функцию НАЧАЛОДНЯ или КОНЕЦДНЯ. Также полезно использовать предопределенные даты, такие как НАЧАЛОГОДА или КОНЕЦМЕСЯЦА, для динамического формирования условий.
Пример распределения документов по сменам в сутках:
- 🌅 С 06:00 до 14:00 — «Утренняя смена».
- ☀️ С 14:00 до 22:00 — «Дневная смена».
- 🌙 С 22:00 до 06:00 — «Ночная смена».
ВЫБРАТЬ
Документ.Дата,
КОГДА ЧАС(Документ.Дата) >= 6 И ЧАС(Документ.Дата) < 14 ТОГДА "Утро"
КОГДА ЧАС(Документ.Дата) >= 14 И ЧАС(Документ.Дата) < 22 ТОГДА "День"
ИНАЧЕ "Ночь"
КОНЕЦ КАК Смена
ИЗ
Документ.ЗаказКлиента КАК Документ
Здесь мы извлекаем час из даты документа и сравниваем его с числовыми константами. Это позволяет быстро сегментировать данные без использования дополнительных регистров сведений.
Оптимизация запросов с датами
Если вы фильтруете или группируете по вычисляемым полям дат (например, по кварталу через КОГДА), индекс по исходной дате может не использоваться эффективно. Старайтесь выносить простые фильтрации по датам в секцию ГДЕ.
Типичные ошибки и рекомендации по оптимизации
Несмотря на простоту синтаксиса, разработчики часто допускают ошибки, влияющие на читаемость и скорость работы. Одна из распространенных проблем — избыточная вложенность, когда код превращается в «лапшу». Если условий становится слишком много, стоит задуматься о вынесении логики в отдельный регистр сведений или обработку в коде 1С.
Другая ошибка — несоответствие типов данных в разных ветках ТОГДА. Если в одной ветке возвращается Число, а в другой Строка, поле результата будет иметь тип Неопределено или универсальный тип, что затруднит дальнейшую агрегацию (суммирование, группировку).
Ключевые рекомендации для поддержания качества кода:
- Используйте отступы для визуального разделения уровней вложенности.
- Давайте псевдонимам полей (КАК) понятные имена, отражающие суть вычисления.
- Избегайте дублирования сложных выражений в условиях — вынесите их в отдельные поля выборки.
- Проверяйте производительность на больших объемах данных с помощью плана выполнения.
⚠️ Внимание: Интерфейс и возможности конструктора запросов могут отличаться в разных версиях платформы 1С:Предприятие 8.3. Некоторые сложные конструкции удобнее писать в текстовом режиме редактора запросов, так как визуальный конструктор может некорректно отображать глубокую вложенность.
☑️ Проверка запроса перед запуском
Правильное использование оператора КОГДА ТОГДА ИНАЧЕ позволяет перенести нагрузку по обработке данных с клиента на сервер СУБД, что критически важно для многопользовательских систем с большим объемом данных.
Часто задаваемые вопросы (FAQ)
Можно ли использовать оператор КОГДА в секции ГДЕ?
Технически да, но это считается плохой практикой. Секция ГДЕ предназначена для фильтрации записей до их выборки. Использование сложных вычисляемых выражений там может помешать СУБД использовать индексы, что приведет к полному сканированию таблицы и замедлению работы. Лучше вынести условие в секцию ГДЕ в явном виде, если это возможно.
Что вернет запрос, если ни одно условие КОГДА не выполнилось и нет блока ИНАЧЕ?
В этом случае в результирующее поле будет записано значение NULL (Неопределено). При дальнейшей работе с этим полем, например, при попытке сложить его с числом, результат также станет NULL. Всегда рекомендуется явно указывать блок ИНАЧЕ для подстраховки.
Как обрабатывать ошибки типов внутри выражения КОГДА?
Язык запросов 1С строго типизирован. Если вы попытаетесь сравнить число со строкой без явного приведения типов, запрос не выполнится и выдаст ошибку компиляции. Убедитесь, что сравниваемые величины совместимы. Для приведения можно использовать функции конвертации, если они доступны в контексте запроса, или готовить данные заранее.
Есть ли ограничение на количество условий КОГДА?
Жесткого ограничения на количество веток в документации не указано, но здравый смысл подсказывает, что запрос с 50 условиями станет неподдерживаемым. Если ветвлений очень много, рассмотрите возможность использования временных таблиц или регистров сведений для хранения правил соответствия, а в запросе делать соединение по этим правилам.