К статье
Практический материал

Разработка и Конфигурация · 11 мин

Конструкция ВЫБОР в запросе 1С 8: как задать условную логику

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

Конструкция ВЫБОР в языке запросов 1С 8 — это аналог оператора CASE в классическом SQL. Она позволяет вычислять значение поля прямо в запросе в зависимости от заданных условий, не прибегая к постобработке выборки в коде. Это удобно при формировании отчётов, выводе статусов документов, классификации номенклатуры и любых ситуациях, где одно поле должно принимать разные значения по логике «если — тогда — иначе».

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

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

Зачем нужен ВЫБОР и где он применяется

Основная задача конструкции — заменить программную обработку выборки декларативной логикой на уровне СУБД. Вместо того чтобы выгружать результат запроса и в цикле проверять условия через «Если…Тогда», разработчик описывает правило один раз в тексте запроса. Такой подход быстрее выполняется и проще читается.

Типовые сценарии использования:

  • вывод текстового статуса документа вместо служебного признака (проведён, помечен на удаление, черновик);
  • классификация данных по диапазонам: «крупный клиент», «средний», «мелкий» — по сумме продаж;
  • замена NULL на осмысленное значение с дополнительной логикой;
  • приведение нескольких значений перечисления к одной группе для группировки в отчёте;
  • условный расчёт суммы: например, брать цену из разных источников в зависимости от валюты документа.

В СКД конструкция ВЫБОР особенно востребована: вычисляемое в запросе поле сразу доступно для настроек отчёта, группировок и отборов без написания обработчиков.

Синтаксис: две формы записи

Язык запросов 1С поддерживает две разновидности конструкции. Первая — поисковая форма, где каждое условие записывается явно и может быть сколь угодно сложным:

ВЫБОР

КОГДА Продажи.Сумма >= 1000000

ТОГДА "Крупный клиент"

КОГДА Продажи.Сумма >= 100000

ТОГДА "Средний клиент"

ИНАЧЕ "Мелкий клиент"

КОНЕЦ КАК КатегорияКлиента

Вторая — простая форма, где сравнивается одно выражение с набором значений. Она короче, но подходит только для проверки на равенство:

ВЫБОР Документ.ВидОперации

КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа)

ТОГДА "Реализация"

КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Возврат)

ТОГДА "Возврат от покупателя"

ИНАЧЕ "Прочее"

КОНЕЦ КАК ОписаниеОперации

Условия проверяются сверху вниз, и срабатывает только первое истинное. Поэтому порядок веток КОГДА имеет значение: более узкие условия должны стоять выше общих. Если поставить проверку «Сумма >= 100000» выше «Сумма >= 1000000», крупные клиенты никогда не попадут в свою категорию.

bsl
ВЫБОР
	КОГДА Документ.Проведен
		ТОГДА "Проведён"
	КОГДА Документ.ПометкаУдаления
		ТОГДА "Помечен на удаление"
	ИНАЧЕ "Черновик"
КОНЕЦ КАК Статус

Практические примеры использования

Вывод статуса документа

Частая задача — показать пользователю понятный статус вместо набора булевых флагов. Запрос выбирает документы и одним полем возвращает их состояние:

ВЫБРАТЬ

Реализация.Ссылка КАК Документ,

ВЫБОР

КОГДА Реализация.ПометкаУдаления

ТОГДА "Помечен на удаление"

КОГДА Реализация.Проведен

ТОГДА "Проведён"

ИНАЧЕ "Не проведён"

КОНЕЦ КАК Статус

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

Обратите внимание: пометка удаления проверяется первой, потому что документ может быть одновременно проведён и помечен — в этом случае важнее показать именно пометку.

Классификация по диапазону значений

При построении отчётов по ABC-анализу или сегментации контрагентов условия строятся на сравнении числовых полей. Здесь

Условный выбор источника данных

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

Если веток КОГДА больше трёх-четырёх и все они проверяют одно поле на равенство значениям перечисления, часто удобнее создать в конфигурации дополнительный реквизит или использовать соединение со вспомогательной таблицей — такой запрос проще поддерживать при добавлении новых значений.
ПЗ
Практическое замечание

Ограничения и правила типизации

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

Второй момент — обработка NULL. Если условие сравнивает поле, которое может принимать NULL (например, поле из левого соединения), сравнение с NULL всегда даёт неопределённый результат, и ветка не сработает. Перед сравнением такое поле следует оборачивать в ЕСТЬNULL:

ВЫБОР

КОГДА ЕСТЬNULL(Остатки.Количество, 0) > 0

ТОГДА "В наличии"

ИНАЧЕ "Нет на складе"

КОНЕЦ КАК НаличиеТовара

Третье правило — ветка ИНАЧЕ фактически обязательна. Формально её можно опустить, но тогда при невыполнении всех условий поле получит значение NULL, что усложнит дальнейшую обработку результата и может «уронить» вычисления в СКД или в коде обхода выборки.

ВЫБОР против ЕСТЬNULL и других альтернатив

Часто разработчики выбирают между ВЫБОР и функцией ЕСТЬNULL. Это не взаимозаменяемые инструменты: ЕСТЬNULL решает ровно одну задачу — подстановку значения вместо NULL, а ВЫБОР реализует произвольную условную логику. Если нужно просто заменить NULL нулём или пустой строкой, ЕСТЬNULL короче и читается лучше.

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

Сравнение вариантов

ВЫБОР КОГДА

Произвольные условия, диапазоны, сложная логика. Ограничение: правила зашиты в тексте запроса.

ЕСТЬNULL

Только замена NULL конкретным значением. Короче и быстрее читается, но не умеет условий.

Соединение с таблицей соответствий

Много правил, которые часто меняются. Требует подготовки временной таблицы или справочника.

Типичные ошибки и как их проверить

Первая распространённая ошибка — неправильный порядок веток КОГДА. Поскольку срабатывает первое истинное условие, общие условия, стоящие выше частных, «перехватывают» записи. Проверка проста: выполните запрос в консоли и убедитесь, что граничные значения попали в ожидаемые категории.

Вторая ошибка — забытая ветка ИНАЧЕ и последующая группировка по полю с NULL. В отчёте появляется строка с пустой категорией, итоги по которой сбивают пользователя с толку. Третья ошибка — сравнение строк без учёта регистра или лишних пробелов в данных: условие «Наименование = "Услуга"» не сработает для значения «Услуга » с пробелом в конце.

Типичные ошибки
01
Общее условие стоит выше частного — узкие категории остаются пустыми, проверяйте порядок веток КОГДА.
02
Нет ветки ИНАЧЕ — в результате появляются NULL, которые ломают группировки и вычисления в СКД.
03
Смешение типов в ветках ТОГДА (строка и число) — запрос падает с ошибкой или возвращает непредсказуемое значение.
04
Сравнение поля из левого соединения без ЕСТЬNULL — условие не срабатывает, запись попадает в ИНАЧЕ.
Контрольные точки

Как проверить результат

Выполнение запроса в консоли
Норма

Запрос выполняется без ошибок, поле с ВЫБОР заполнено во всех строках

Тревожный признак

Ошибка несовместимости типов или пустые значения в части строк

Граничные значения
Норма

Значения на границах диапазонов попадают ровно в одну категорию

Тревожный признак

Граничная запись попала не в ту категорию или потерялась

Итоги в отчёте СКД
Норма

Сумма по категориям сходится с общим итогом без учёта ВЫБОР

Тревожный признак

Появилась группа с пустым наименованием или расхождение итогов

Порядок разработки запроса с ВЫБОР

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

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

Часто задаваемые вопросы

Можно ли использовать ВЫБОР в условии ГДЕ?

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

Есть ли ограничение на количество веток КОГДА?

Жёсткого документированного ограничения платформа не накладывает, однако конструкции с десятками веток тяжело читаются и сопровождаются. При большом числе правил лучше перенести соответствия во временную таблицу или справочник и использовать соединение.

Как в ВЫБОР сравнить поле с пустой ссылкой?

Используйте функцию ЗНАЧЕНИЕ с указанием типа, например: КОГДА Поле = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка). Для составного типа поля корректнее проверять на NULL или применять ЕСТЬNULL с приведением к конкретному типу.

Работает ли ВЫБОР в динамических списках?

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

Чем ВЫБОР отличается от функции ВЫРАЗИТЬ?

Это разные инструменты: ВЫРАЗИТЬ приводит значение к указанному типу (например, обрезает строку или уточняет составной тип ссылки), а ВЫБОР выбирает значение по условию. Их часто комбинируют: внутри веток ТОГДА применяют ВЫРАЗИТЬ, чтобы привести возвращаемые значения к единому типу.

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

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

Итог

Что важно запомнить

ВЫБОР в запросе 1С 8 — это CASE-логика на уровне СУБД: условия проверяются сверху вниз, срабатывает первое истинное. Все значения веток должны быть одного типа, ветка ИНАЧЕ — обязательна, поля из соединений перед сравнением оборачивайте в ЕСТЬNULL. Результат проверяйте на граничных значениях и сверкой итогов.