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

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

Конструкция «Выбор Когда» с перечислением в 1С

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

Конструкция ВЫБОР КОГДА ... ТОГДА ... КОНЕЦ в языке запросов 1С — аналог оператора CASE в SQL. Она позволяет вернуть разные значения в зависимости от условий, и чаще всего применяется для преобразования значений перечислений в читаемый текст, числовые коэффициенты или признаки для группировки и отбора.

Типичная задача выглядит так: в отчете нужно показать не ссылку на перечисление ВидыОперацийПоступление, а понятное пользователю слово «Товары», «Услуги» или «Основные средства». Другой частый сценарий — рассчитать сумму с разным коэффициентом в зависимости от ставки НДС или вида договора. В обоих случаях значение перечисления сравнивается с конкретными элементами через конструкцию ЗНАЧЕНИЕ(Перечисление.Имя.Элемент).

Ниже разобран синтаксис, рабочие примеры, ограничения конструкции и типичные ошибки, которые приводят к пустым колонкам или ошибкам выполнения запроса.

Синтаксис конструкции «Выбор Когда» в запросе 1С

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

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

ВЫБОР

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

ТОГДА "Товары"

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

ТОГДА "Услуги"

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

КОНЕЦ КАК ВидОперацииТекстом

Как вывести текст вместо ссылки на перечисление

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

Пример для перечисления ставок НДС: поле СтавкаНДС сравнивается с элементами НДС20, НДС10 и БезНДС, а в результате выводится строка «20 %», «10 %» или «Без НДС». Такой подход позволяет сразу форматировать данные под печатную форму или выгрузку в Excel без постобработки в коде.

Если значений много, а текст должен совпадать с синонимом, иногда проще вывести само перечисление и отформатировать его средствами СКД или функцией Представление() уже в коде. Конструкция «Выбор Когда» оправдана, когда текст отличается от стандартного представления или нужна дополнительная логика.

bsl
ВЫБОР
	КОГДА Таб.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20)
		ТОГДА "20 %"
	КОГДА Таб.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10)
		ТОГДА "10 %"
	КОГДА Таб.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.БезНДС)
		ТОГДА "Без НДС"
	ИНАЧЕ "Не определено"
КОНЕЦ КАК СтавкаНДСТекстом

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

Вторая большая группа задач — вычисления, где коэффициент или формула зависят от значения перечисления. Например, сумма НДС рассчитывается по-разному для ставок 20 %, 10 % и «без НДС»: в ветках ТОГДА размещаются выражения Сумма 20 / 120, Сумма 10 / 110 и 0.

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

Для числовых расчетов полезно явно приводить результат через ВЫРАЗИТЬ(... КАК ЧИСЛО(15, 2)), чтобы гарантировать разрядность и избежать потери копеек при промежуточных делениях. Это особенно важно, когда результат участвует в последующей группировке с суммированием.

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

Фильтрация и группировка по значениям перечисления

«Выбор Когда» используется не только в списке полей, но и для формирования признаков, по которым затем группируются или фильтруются данные. Например, документы можно разбить на «Реализация», «Возврат» и «Прочие» по виду операции и сгруппировать итоги по этому вычисляемому признаку в итоговом запросе или в СКД.

Для простого отбора по одному значению конструкция не нужна: достаточно условия ГДЕ Поле = ЗНАЧЕНИЕ(Перечисление.Имя.Элемент) или параметра-списка с оператором В (&Список). «Выбор Когда» оправдан, когда по разным значениям перечисления нужно применить разную логику или свести несколько значений в одну категорию.

При группировке по вычисляемому полю с «Выбор Когда» в чистом запросе потребуется вложенный запрос: сначала вычисляется признак во внутреннем запросе, затем во внешнем выполняется СГРУППИРОВАТЬ ПО по нему. В СКД это делается проще — вычисляемое поле добавляется в набор ресурсов и группировок через настройки отчета.

Особенности и ограничения конструкции

В языке запросов 1С есть только поисковая форма CASE: условие в каждой ветке пишется полностью, включая имя поля. Сокращенной формы вида «CASE поле WHEN значение» нет, поэтому сравнение повторяется в каждой ветке КОГДА. Это делает текст длиннее, но позволяет комбинировать разные поля и условия в одной конструкции.

Сравнение с NULL внутри «Выбор Когда» работает по-особенному: равенство с NULL никогда не истинно. Если поле может быть не заполнено (например, в необязательном реквизите), проверку делают через Поле ЕСТЬ NULL в отдельной ветке КОГДА, причем ее лучше ставить первой, чтобы она не перекрывалась другими условиями.

Еще одно ограничение — производительность при большом числе веток. Десятки условий «Когда» в поле, вычисляемом для миллионов строк, замедляют запрос. Если значений много и соответствие фиксировано, часто эффективнее завести соответствие в коде, передать его в запрос временной таблицей и соединить с основными данными.

Маршрут решения

Как выбрать подход

Нужно заменить 2–5 значений перечисления текстом или коэффициентомИспользуйте ВЫБОР КОГДА прямо в поле запроса
Нужен простой отбор по одному или нескольким значениямИспользуйте ГДЕ Поле = ЗНАЧЕНИЕ(...) или Поле В (&Список) без ВЫБОР
Значений много и соответствие меняется без обновления конфигурацииПередайте соответствие временной таблицей и соедините с запросом
Поле может быть не заполненоПервой веткой добавьте КОГДА Поле ЕСТЬ NULL ТОГДА значение_для_пустого

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

Самая частая ошибка — использование синонима вместо имени элемента в ЗНАЧЕНИЕ(). Запрос при этом не выполнится вообще: конструктор сообщит, что поле не найдено. Ошибка ловится сразу, но только если запрос реально выполняется — в редко используемых ветках кода она может всплыть у пользователя.

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

Третья группа ошибок связана с типами: смешение строки и числа в ветках, сравнение перечисления со строкой вместо ЗНАЧЕНИЕ(), сравнение с NULL через равенство. Все они диагностируются выполнением запроса в консоли запросов на копии базы с просмотром типа итогового поля.

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

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

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

Запрос выполняется без ошибок, поле заполнено

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

Ошибка «Поле не найдено» или пустая колонка

Значение поля для каждого элемента перечисления
Норма

Каждое значение дает ожидаемый результат

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

Часть строк ушла в ИНАЧЕ без причины

Сумма детальных строк против итога
Норма

Суммы сходятся

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

Расхождение — признак NULL в вычисляемом поле

Тип итогового поля
Норма

Единый тип (число или строка)

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

Составной тип или NULL в части строк

Альтернативы конструкции «Выбор Когда»

Когда значений перечисления много или соответствие должно меняться без доработки конфигурации, «Выбор Когда» заменяют соединением с временной таблицей. В коде формируется таблица значений с колонками «ЗначениеПеречисления» и «Результат», помещается в запрос через ПОМЕСТИТЬ, и основная выборка соединяется с ней левым соединением. Такое решение проще поддерживать, но требует больше кода.

В отчетах на СКД часть задач решается без изменения запроса: вычисляемые поля с собственными выражениями, форматирование полей и пользовательские поля в настройках. Это удобно, когда логика нужна только для представления, а не для расчетов.

Для единичных случаев в коде вне запроса используется обычный оператор Если ... ИначеЕсли или соответствие: СоответствиеСтавок.Получить(СтавкаНДС). Это читабельнее и проще отлаживается, но неприменимо внутри запроса — выбор инструмента зависит от того, где именно нужен результат.

Сравнение подходов

ВЫБОР КОГДА в запросе

Подходит для 2–10 фиксированных значений; логика хранится в тексте запроса и проверяется при компиляции

Временная таблица соответствий

Подходит при большом числе значений или когда соответствие задается данными; требует кода для подготовки таблицы

Вычисляемые поля СКД

Подходит для оформления представления в отчете без изменения основного запроса

Если/Соответствие в коде

Подходит для логики вне запроса; проще отладка, но нельзя использовать внутри выборки

Итог

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

Перечисление в «Выбор Когда» сравнивается через ЗНАЧЕНИЕ(Перечисление.Имя.Элемент) по имени из конфигуратора. Всегда добавляйте ИНАЧЕ, держите единый тип результата во всех ветках и проверяйте NULL отдельным условием ЕСТЬ NULL. При большом числе значений выносите соответствие во временную таблицу.

Частые вопросы

Можно ли в «Выбор Когда» сравнивать перечисление со строкой?

Нет. Перечисление — ссылочный тип, и сравнение со строкой всегда ложно. Нужно использовать ЗНАЧЕНИЕ(Перечисление.Имя.Элемент), где указывается имя элемента из конфигуратора, а не его синоним.

Что будет, если не указать ветку ИНАЧЕ?

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

Как обработать ситуацию, когда поле перечисления не заполнено?

Добавьте первой веткой КОГДА Поле ЕСТЬ NULL ТОГДА значение_для_пустого. Сравнение через равенство с NULL не работает — условие никогда не будет истинным.

Можно ли использовать «Выбор Когда» в секции ГДЕ?

Технически да, но для фильтрации это лишнее: проще написать ГДЕ Поле = ЗНАЧЕНИЕ(...) или Поле В (&СписокЗначений). «Выбор Когда» в условиях оправдан редко и ухудшает читаемость запроса.

Почему запрос перестал работать после обновления конфигурации?

Вероятная причина — переименование элемента перечисления, на который ссылается ЗНАЧЕНИЕ(). Имя в запросе должно совпадать с именем в метаданных. После обновлений проверяйте все запросы, где перечисления используются явно.

Как сгруппировать данные по результату «Выбор Когда»?

В обычном запросе — через вложенный запрос: внутренний вычисляет признак, внешний группирует по нему. В СКД достаточно добавить вычисляемое поле и использовать его в группировке настроек отчета.