Разработка и Конфигурация · 11 мин
Конструкция ВЫБОР в запросе 1С 8: как задать условную логику
Как использовать конструкцию ВЫБОР КОГДА в запросах 1С 8: синтаксис, примеры с условиями и значениями, сравнение с ЕСТЬNULL, типичные ошибки и проверка результата.
Конструкция ВЫБОР в языке запросов 1С 8 — это аналог оператора CASE в классическом SQL. Она позволяет вычислять значение поля прямо в запросе в зависимости от заданных условий, не прибегая к постобработке выборки в коде. Это удобно при формировании отчётов, выводе статусов документов, классификации номенклатуры и любых ситуациях, где одно поле должно принимать разные значения по логике «если — тогда — иначе».
Конструкция работает во всех современных версиях платформы 1С:Предприятие 8 и поддерживается в консоли запросов, схеме компоновки данных (СКД), динамических списках и программно создаваемых запросах. Понимание её синтаксиса и ограничений избавляет от лишних циклов обхода результата и упрощает поддержку кода.
Ниже разобраны обе формы записи ВЫБОР — простая и поисковая, типичные сценарии применения, ограничения по типам данных, а также ошибки, которые чаще всего приводят к неверным результатам или падению запроса.
Зачем нужен ВЫБОР и где он применяется
Основная задача конструкции — заменить программную обработку выборки декларативной логикой на уровне СУБД. Вместо того чтобы выгружать результат запроса и в цикле проверять условия через «Если…Тогда», разработчик описывает правило один раз в тексте запроса. Такой подход быстрее выполняется и проще читается.
Типовые сценарии использования:
- вывод текстового статуса документа вместо служебного признака (проведён, помечен на удаление, черновик);
- классификация данных по диапазонам: «крупный клиент», «средний», «мелкий» — по сумме продаж;
- замена NULL на осмысленное значение с дополнительной логикой;
- приведение нескольких значений перечисления к одной группе для группировки в отчёте;
- условный расчёт суммы: например, брать цену из разных источников в зависимости от валюты документа.
В СКД конструкция ВЫБОР особенно востребована: вычисляемое в запросе поле сразу доступно для настроек отчёта, группировок и отборов без написания обработчиков.
Синтаксис: две формы записи
Язык запросов 1С поддерживает две разновидности конструкции. Первая — поисковая форма, где каждое условие записывается явно и может быть сколь угодно сложным:
ВЫБОР
КОГДА Продажи.Сумма >= 1000000
ТОГДА "Крупный клиент"
КОГДА Продажи.Сумма >= 100000
ТОГДА "Средний клиент"
ИНАЧЕ "Мелкий клиент"
КОНЕЦ КАК КатегорияКлиента
Вторая — простая форма, где сравнивается одно выражение с набором значений. Она короче, но подходит только для проверки на равенство:
ВЫБОР Документ.ВидОперации
КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа)
ТОГДА "Реализация"
КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Возврат)
ТОГДА "Возврат от покупателя"
ИНАЧЕ "Прочее"
КОНЕЦ КАК ОписаниеОперации
Условия проверяются сверху вниз, и срабатывает только первое истинное. Поэтому порядок веток КОГДА имеет значение: более узкие условия должны стоять выше общих. Если поставить проверку «Сумма >= 100000» выше «Сумма >= 1000000», крупные клиенты никогда не попадут в свою категорию.
ВЫБОР
КОГДА Документ.Проведен
ТОГДА "Проведён"
КОГДА Документ.ПометкаУдаления
ТОГДА "Помечен на удаление"
ИНАЧЕ "Черновик"
КОНЕЦ КАК СтатусПрактические примеры использования
Вывод статуса документа
Частая задача — показать пользователю понятный статус вместо набора булевых флагов. Запрос выбирает документы и одним полем возвращает их состояние:
ВЫБРАТЬ
Реализация.Ссылка КАК Документ,
ВЫБОР
КОГДА Реализация.ПометкаУдаления
ТОГДА "Помечен на удаление"
КОГДА Реализация.Проведен
ТОГДА "Проведён"
ИНАЧЕ "Не проведён"
КОНЕЦ КАК Статус
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
Обратите внимание: пометка удаления проверяется первой, потому что документ может быть одновременно проведён и помечен — в этом случае важнее показать именно пометку.
Классификация по диапазону значений
При построении отчётов по ABC-анализу или сегментации контрагентов условия строятся на сравнении числовых полей. Здесь
Условный выбор источника данных
ВЫБОР позволяет брать значение из разных полей в зависимости от контекста. Например, если в документе не указан договор, подставлять основной договор контрагента. Для таких сценариев условие обычно строится на проверке поля на NULL или на пустую ссылку.
Если веток КОГДА больше трёх-четырёх и все они проверяют одно поле на равенство значениям перечисления, часто удобнее создать в конфигурации дополнительный реквизит или использовать соединение со вспомогательной таблицей — такой запрос проще поддерживать при добавлении новых значений.
Ограничения и правила типизации
Главное ограничение конструкции — все значения в ветках ТОГДА и ИНАЧЕ должны быть приводимы к одному типу. Если одна ветка возвращает строку, а другая — число, запрос завершится с ошибкой либо результат будет непредсказуемым в зависимости от режима совместимости. Смешивать ссылочные и примитивные типы в одной конструкции нельзя.
Второй момент — обработка NULL. Если условие сравнивает поле, которое может принимать NULL (например, поле из левого соединения), сравнение с NULL всегда даёт неопределённый результат, и ветка не сработает. Перед сравнением такое поле следует оборачивать в ЕСТЬNULL:
ВЫБОР
КОГДА ЕСТЬNULL(Остатки.Количество, 0) > 0
ТОГДА "В наличии"
ИНАЧЕ "Нет на складе"
КОНЕЦ КАК НаличиеТовара
Третье правило — ветка ИНАЧЕ фактически обязательна. Формально её можно опустить, но тогда при невыполнении всех условий поле получит значение NULL, что усложнит дальнейшую обработку результата и может «уронить» вычисления в СКД или в коде обхода выборки.
ВЫБОР против ЕСТЬNULL и других альтернатив
Часто разработчики выбирают между ВЫБОР и функцией ЕСТЬNULL. Это не взаимозаменяемые инструменты: ЕСТЬNULL решает ровно одну задачу — подстановку значения вместо NULL, а ВЫБОР реализует произвольную условную логику. Если нужно просто заменить NULL нулём или пустой строкой, ЕСТЬNULL короче и читается лучше.
Альтернативой сложным многоуровневым ВЫБОР служит соединение с заранее подготовленной таблицей соответствий (временной таблицей или справочником). Такой подход выигрывает, когда правил много и они меняются пользователями без доработки кода.
Сравнение вариантов
Произвольные условия, диапазоны, сложная логика. Ограничение: правила зашиты в тексте запроса.
Только замена NULL конкретным значением. Короче и быстрее читается, но не умеет условий.
Много правил, которые часто меняются. Требует подготовки временной таблицы или справочника.
Типичные ошибки и как их проверить
Первая распространённая ошибка — неправильный порядок веток КОГДА. Поскольку срабатывает первое истинное условие, общие условия, стоящие выше частных, «перехватывают» записи. Проверка проста: выполните запрос в консоли и убедитесь, что граничные значения попали в ожидаемые категории.
Вторая ошибка — забытая ветка ИНАЧЕ и последующая группировка по полю с NULL. В отчёте появляется строка с пустой категорией, итоги по которой сбивают пользователя с толку. Третья ошибка — сравнение строк без учёта регистра или лишних пробелов в данных: условие «Наименование = "Услуга"» не сработает для значения «Услуга » с пробелом в конце.
Как проверить результат
Запрос выполняется без ошибок, поле с ВЫБОР заполнено во всех строках
Ошибка несовместимости типов или пустые значения в части строк
Значения на границах диапазонов попадают ровно в одну категорию
Граничная запись попала не в ту категорию или потерялась
Сумма по категориям сходится с общим итогом без учёта ВЫБОР
Появилась группа с пустым наименованием или расхождение итогов
Порядок разработки запроса с ВЫБОР
Работу над запросом удобно вести итеративно: сначала собрать базовую выборку без условной логики, затем добавить конструкцию ВЫБОР и только потом подключать группировки и итоги. Так проще локализовать ошибку — если запрос упал, причина либо в типах значений, либо в синтаксисе условий.
- 1Сформируйте базовый запрос с нужными таблицами и проверьте его выполнение в консоли запросов.
- 2Добавьте конструкцию ВЫБОР с ветками КОГДА, расположив условия от частного к общему.
- 3Укажите ветку ИНАЧЕ со значением того же типа, что и в ветках ТОГДА.
- 4Проверьте результат на граничных значениях и записях с NULL в сравниваемых полях.
- 5Подключите поле к группировкам или ресурсам СКД и сверьте итоги с контрольными данными.
Часто задаваемые вопросы
Можно ли использовать ВЫБОР в условии ГДЕ?
Да, конструкция допустима в секции ГДЕ, но чаще в этом нет необходимости — обычные логические операторы И, ИЛИ читаются проще. ВЫБОР в отборе оправдан, когда критерий фильтрации сам является вычисляемой категорией, которая уже определена в списке полей.
Есть ли ограничение на количество веток КОГДА?
Жёсткого документированного ограничения платформа не накладывает, однако конструкции с десятками веток тяжело читаются и сопровождаются. При большом числе правил лучше перенести соответствия во временную таблицу или справочник и использовать соединение.
Как в ВЫБОР сравнить поле с пустой ссылкой?
Используйте функцию ЗНАЧЕНИЕ с указанием типа, например: КОГДА Поле = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка). Для составного типа поля корректнее проверять на NULL или применять ЕСТЬNULL с приведением к конкретному типу.
Работает ли ВЫБОР в динамических списках?
Да, конструкция полностью поддерживается в произвольных запросах динамических списков. Учитывайте только, что сложная условная логика в основной таблице списка выполняется при каждом обновлении, поэтому на больших объёмах стоит следить за производительностью.
Чем ВЫБОР отличается от функции ВЫРАЗИТЬ?
Это разные инструменты: ВЫРАЗИТЬ приводит значение к указанному типу (например, обрезает строку или уточняет составной тип ссылки), а ВЫБОР выбирает значение по условию. Их часто комбинируют: внутри веток ТОГДА применяют ВЫРАЗИТЬ, чтобы привести возвращаемые значения к единому типу.
Можно ли вкладывать один ВЫБОР в другой?
Да, вложенные конструкции допустимы — внутри ветки ТОГДА или ИНАЧЕ можно разместить ещё один ВЫБОР. Однако вложенность глубже двух уровней сильно ухудшает читаемость; такую логику лучше пересмотреть в сторону плоской цепочки условий или соединения с таблицей соответствий.
Что важно запомнить
ВЫБОР в запросе 1С 8 — это CASE-логика на уровне СУБД: условия проверяются сверху вниз, срабатывает первое истинное. Все значения веток должны быть одного типа, ветка ИНАЧЕ — обязательна, поля из соединений перед сравнением оборачивайте в ЕСТЬNULL. Результат проверяйте на граничных значениях и сверкой итогов.