Оператор Когда-Тогда является одним из фундаментальных инструментов в арсенале разработчика платформы 1С:Предприятие 8. Эта конструкция позволяет реализовать условную логику непосредственно внутри запроса, не выгружая данные в программный код для последующей обработки. Понимание принципов ее работы критически важно для написания производительных отчетов и сложных алгоритмов выборки.
В отличие от программного кода, где мы привыкли использовать конструкции Если..Тогда..Иначе, язык запросов 1С требует специфического синтаксиса для ветвления. Использование ВЫБОР (так часто называют этот оператор разработчики) позволяет формировать итоговые наборы данных "на лету". Это существенно снижает нагрузку на сервер приложений и ускоряет формирование отчетов больших объемов.
Рассмотрим детально, как правильно строить такие выражения, какие подводные камни существуют при работе с типами данных и как использовать эту мощь для решения реальных бизнес-задач. Мы разберем синтаксис от простого к сложному, уделяя особое внимание типизации возвращаемых значений.
Синтаксис и базовая структура оператора
Фундамент конструкции строится вокруг ключевого слова ВЫБОР. Именно с него начинается блок условной логики. Внутри этого блока последовательно перечисляются условия проверки. Каждое условие начинается со слова КОГДА, за которым следует логическое выражение. Если выражение истинно, выполняется ветвь ТОГДА.
Важно отметить, что порядок следования условий имеет значение. Система проверяет их последовательно сверху вниз. Как только найдено первое истинное условие, соответствующее значение возвращается, и проверка остальных условий прекращается. Это поведение аналогично оператору switch-case или цепочке if-elif в других языках программирования.
Для обработки ситуаций, когда ни одно из условий не выполнилось, предусмотрена ветвь ИНАЧЕ. Она является опциональной, но крайне рекомендуемой к использованию для обеспечения предсказуемости результата. Завершается вся конструкция ключевым словом КОНЕЦ. Без него запрос не будет выполнен, и конфигуратор выдаст ошибку синтаксиса.
Всегда завершайте конструкцию ВЫБОР словом КОНЕЦ, иначе запрос не скомпилируется.
Пример базовой структуры выглядит следующим образом:
ВЫБОР
КОГДА Условие1 ТОГДА Значение1
КОГДА Условие2 ТОГДА Значение2
ИНАЧЕ ЗначениеПоУмолчанию
КОНЕЦ
Вложенные условия и логические выражения
Внутри блока КОГДА можно использовать сложные логические выражения. Разработчик вправе комбинировать операторы сравнения (=, <, >, <>) с логическими связками И, ИЛИ, НЕ. Это позволяет описывать бизнес-правила любой сложности непосредственно на языке запросов.
Часто возникает необходимость проверить несколько полей одновременно. Например, нужно выделить товары, у которых остаток меньше нормы, И при этом они не являются помеченными на удаление. В таком случае условие будет выглядеть как составное выражение. Платформа 1С корректно обрабатывает приоритеты операций, но для читаемости кода рекомендуется использовать скобки.
Особое внимание следует уделить проверке на заполненность. В 1С пустая строка и значение NULL (Неопределено) — это разные сущности. Для корректной работы конструкции Когда-Тогда важно понимать разницу между ЕСТЬ NULL и проверкой на пустую строку. Ошибка в этом моменте может привести к тому, что часть документов не попадет в нужную категорию.
Рассмотрим пример сложного условия для классификации контрагентов:
ВЫБОР
КОГДА (Контрагенты.Вид = ЗНАЧЕНИЕ(Перечисление.ВидыКонтрагентов.ЮрЛицо))
И (Контрагенты.ИНН <> "") ТОГДА "Юридическое лицо"
КОГДА Контрагенты.Вид = ЗНАЧЕНИЕ(Перечисление.ВидыКонтрагентов.ФизЛицо) ТОГДА "Физическое лицо"
ИНАЧЕ "Не определено"
КОНЕЦ
Типизация возвращаемых значений
Один из самых критичных аспектов работы с оператором ВЫБОР — это требование к типам данных. Все значения, возвращаемые в ветвях ТОГДА и ИНАЧЕ, должны быть совместимы. Платформа 1С формирует итоговый тип поля как объединение всех возможных типов, которые могут вернуться из разных веток.
Если в одной ветке вы возвращаете число, а в другой — строку, итоговое поле в результирующей таблице будет иметь составной тип ЧислоИлиСтрока. Это может вызвать проблемы при дальнейшем использовании результата запроса, например, при попытке выполнить математические операции или группировку. Консоль запросов или отчет могут выдать ошибку типов.
Чтобы избежать проблем, рекомендуется явно приводить типы данных к единому знаменателю. Если логика требует возврата разных сущностей, лучше всего приводить их к строковому представлению или использовать значение NULL (Неопределено) в качестве заглушки для несовместимых типов, хотя последний вариант требует аккуратности.
Все ветки ТОГДА и ИНАЧЕ должны возвращать данные совместимых типов, иначе возникнет ошибка выполнения или некорректная работа отчета.
Приведем таблицу с примерами совместимости типов в конструкции выбора:
| Ветка 1 (Тип) | Ветка 2 (Тип) | Итоговый тип поля | Рекомендация |
|---|---|---|---|
| Число | Число | Число | Оптимально |
| Строка | Строка | Строка | Оптимально |
| Число | Строка | ЧислоИлиСтрока | Привести к строке |
| Дата | Число | ДатаИлиЧисло | Избегать |
| СправочникСсылка | Неопределено | СправочникСсылка | Допустимо |
Использование в агрегатных функциях и группировках
Мощь конструкции Когда-Тогда раскрывается в полной мере при использовании внутри агрегатных функций, таких как СУММА, МИН, МАКС или КОЛИЧЕСТВО. Это позволяет выполнять так называемое "условное суммирование" прямо на уровне СУБД, не загружая лишние данные в память.
Представьте задачу: нужно посчитать общую сумму продаж, но отдельно выделить сумму продаж со скидкой и сумму продаж без скидки. Вместо того чтобы делать два разных запроса или фильтровать данные в цикле, мы можем использовать вложенный ВЫБОР внутри функции СУММА. Это классический паттерн для построения аналитических отчетов.
При группировке данных (СГРУППИРОВАТЬ ПО) оператор выбора также незаменим. Он позволяет создавать виртуальные измерения. Например, можно сгруппировать документы не по конкретным складам, а по регионам, определив принадлежность склада к региону через конструкцию КОГДА-ТОГДА прямо в списке полей группировки.
Пример условного суммирования
СУММА(ЕСЛИ Скидка > 0 ТОГДА Сумма ИНАЧЕ 0 КОНЕЦ) как СуммаСоСкидкой
Синтаксис вложенного выбора в агрегатной функции:
СУММА(
ВЫБОР
КОГДА РегистрНакопления.Продажи.Скидка > 0 ТОГДА РегистрНакопления.Продажи.Сумма
ИНАЧЕ 0
КОНЕЦ
) КАК СуммаПродажСоСкидкой
Производительность и оптимизация запросов
Вопрос производительности при использовании ВЫБОР часто вызывает споры. Сама по себе конструкция не является "тяжелой" для СУБД, так как современные серверы баз данных (MS SQL, PostgreSQL) эффективно оптимизируют такие выражения. Однако неправильное использование может привести к_full scan_ таблиц.
Главное правило оптимизации: условия в блоке КОГДА должны по возможности опираться на индексируемые поля. Если вы проверяете поле, по которому нет индекса, или применяете к полю функцию, которая препятствует использованию индекса, скорость выполнения запроса может упасть на больших объемах данных.
⚠️ Внимание: Избегайте применения функций к полям таблиц внутри условия КОГДА, если это возможно. Например, вместоГОД(Дата) = 2026лучше использовать диапазон датДата МЕЖДУ.. И.., чтобы задействовать индекс по дате.
Также стоит помнить о порядке условий. Хотя оптимизатор запросов может менять порядок выполнения, логичнее ставить наиболее вероятные условия в начало списка. Это может незначительно ускорить обработку в интерпретируемом режиме или при специфических планах выполнения.
☑️ Оптимизация конструкции ВЫБОР
Типичные ошибки и отладка
При разработке сложных запросов с ветвлением разработчики часто сталкиваются с рядом типовых ошибок. Самая распространенная из них — несоответствие типов возвращаемых значений, о котором уже говорилось выше. Консоль запросов в таком случае обычно выдает сообщение о невозможности сравнения или преобразования типов.
Другая частая ошибка — забытое ключевое слово КОНЕЦ. В больших запросах с несколькими вложенными конструкциями ВЫБОР легко потерять счет скобкам и завершающим словам. Внимательное форматирование кода и использование отступов помогают избежать этой проблемы.
Для отладки сложных условий рекомендуется выносить конструкцию ВЫБОР в отдельное поле временной таблицы или сразу в результирующее поле с понятным именем. Это позволяет визуально проверить, какое значение попадает в каждую строку результата, и убедиться в корректности логики.
⚠️ Внимание: Интерфейс и возможности Консоли запросов могут отличаться в разных конфигурациях и версиях платформы. Всегда проверяйте актуальность инструментов отладки в вашей конкретной версии 1С.
Если запрос выполняется медленно, попробуйте упростить условия КОГДА. Иногда разбивка одного сложного запроса с множеством вложенных выборов на два более простых запроса с последующим соединением (или объединением) дает выигрыш в производительности за счет более оптимального плана выполнения.
Используйте временные таблицы для сохранения промежуточных результатов сложного ВЫБОР, если этот результат используется многократно в дальнейших соединениях.
Практические примеры из жизни
Рассмотрим реальную задачу из сферы торговли. Необходимо сформировать отчет по остаткам товаров, где нужно динамически определить статус товара: "Хит", "Новинка", "Залежалый" или "Обычный". Критерии зависят от даты поступления и объема продаж за последний месяц.
Вместо того чтобы писать обработку на встроенном языке, мы реализуем это в одном запросе. Это позволит вывести отчет мгновенно, даже если в базе миллионы движений. Логика будет заключаться в проверке даты регистрации номенклатуры и сумм продаж из регистра накопления.
Такой подход делает отчет гибким. Изменив условия в тексте запроса, пользователь (или администратор) может быстро перенастроить логику классификации без изменения программного кода конфигурации. Это особенно удобно для оперативной аналитики.
ВЫБОР
КОГДА Номенклатура.ДатаСоздания > ДОБАВИТЬКДАТЕ(СЕГОДНЯ(), МЕСЯЦ, -1) ТОГДА "Новинка"
КОГДА Остатки.КоличествоОстаток > 1000 ТОГДА "Хит"
КОГДА Номенклатура.ДатаПоследнейПродажи < ДОБАВИТЬКДАТЕ(СЕГОДНЯ(), МЕСЯЦ, -6) ТОГДА "Залежалый"
ИНАЧЕ "Обычный"
КОНЕЦ КАК СтатусТовара
Как обрабатывать NULL в конструкции Когда-Тогда?
Для проверки на NULL используется специальный синтаксис ЕСТЬ NULL Поле. Если поле содержит неопределенное значение, условие вернет Истину.
Можно ли использовать ВЫБОР в условии ГДЕ?
Да, конструкция ВЫБОР допустима в секции ГДЕ. В этом случае она должна возвращать булево значение (Истина/Ложь). Например: ГДЕ (ВЫБОР КОГДА Сумма > 1000 ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ) = ИСТИНА.
В чем разница между ВЫБОР и функцией ЕСТЬNULL?
Функция ЕСТЬNULL(Поле, Замена) является частным, упрощенным случаем оператора ВЫБОР. Она проверяет только на неопределенность. Оператор ВЫБОР универсален и позволяет проверять любые сложные логические условия, а не только заполненность одного поля.
Можно ли вкладывать ВЫБОР друг в друга?
Да, поддерживается неограниченная вложенность. Вы можете использовать конструкцию ВЫБОР внутри ветки ТОГДА другого ВЫБОР. Главное — соблюдать баланс ключевых слов ВЫБОР и КОНЕЦ и следить за читаемостью кода.
Влияет ли порядок условий КОГДА на результат?
Да, влияет. Проверка идет строго сверху вниз. Если первое условие истинно, остальные игнорируются. Поэтому более специфичные условия следует располагать выше, а общие — ниже, ближе к ветви ИНАЧЕ.