Разработка и Конфигурация · 12 мин
Конструкция «Выбор Когда» с перечислением в 1С
Как использовать конструкцию ВЫБОР КОГДА с перечислениями в запросах 1С: синтаксис, примеры кода, сравнение с ВЫРАЗИТЬ, типичные ошибки и проверка результата.
Конструкция ВЫБОР КОГДА ... ТОГДА ... КОНЕЦ в языке запросов 1С — аналог оператора CASE в SQL. Она позволяет вернуть разные значения в зависимости от условий, и чаще всего применяется для преобразования значений перечислений в читаемый текст, числовые коэффициенты или признаки для группировки и отбора.
Типичная задача выглядит так: в отчете нужно показать не ссылку на перечисление ВидыОперацийПоступление, а понятное пользователю слово «Товары», «Услуги» или «Основные средства». Другой частый сценарий — рассчитать сумму с разным коэффициентом в зависимости от ставки НДС или вида договора. В обоих случаях значение перечисления сравнивается с конкретными элементами через конструкцию ЗНАЧЕНИЕ(Перечисление.Имя.Элемент).
Ниже разобран синтаксис, рабочие примеры, ограничения конструкции и типичные ошибки, которые приводят к пустым колонкам или ошибкам выполнения запроса.
Синтаксис конструкции «Выбор Когда» в запросе 1С
Общий вид конструкции: ВЫБОР КОГДА условие1 ТОГДА значение1 КОГДА условие2 ТОГДА значение2 ИНАЧЕ значение_по_умолчанию КОНЕЦ. Условий КОГДА может быть сколько угодно, они проверяются последовательно, и срабатывает первая истинная ветка. Ветка ИНАЧЕ формально необязательна, но без нее при несовпадении всех условий поле получит значение NULL, что часто ломает дальнейшие вычисления и группировки.
Для сравнения с перечислением используется функция ЗНАЧЕНИЕ(), которая возвращает ссылку на конкретный элемент перечисления по его имени, заданному в конфигураторе. Важно: указывается именно имя элемента в метаданных, а не синоним, который видит пользователь. Если элемент переименуют в конфигураторе, запрос перестанет компилироваться — это одновременно и защита от тихих ошибок, и источник проблем при обновлениях.
ВЫБОР
КОГДА Док.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийПоступление.Товары)
ТОГДА "Товары"
КОГДА Док.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийПоступление.Услуги)
ТОГДА "Услуги"
ИНАЧЕ "Прочее"
КОНЕЦ КАК ВидОперацииТекстом
Как вывести текст вместо ссылки на перечисление
Самый распространенный сценарий — заменить ссылку на перечисление читаемой строкой в отчете или динамическом списке. Ссылка сама по себе выводится как представление, но в группировках, выгрузках и соединениях удобнее работать с явным текстом. Для этого каждое значение перечисления сопоставляется со строковым литералом.
Пример для перечисления ставок НДС: поле СтавкаНДС сравнивается с элементами НДС20, НДС10 и БезНДС, а в результате выводится строка «20 %», «10 %» или «Без НДС». Такой подход позволяет сразу форматировать данные под печатную форму или выгрузку в Excel без постобработки в коде.
Если значений много, а текст должен совпадать с синонимом, иногда проще вывести само перечисление и отформатировать его средствами СКД или функцией Представление() уже в коде. Конструкция «Выбор Когда» оправдана, когда текст отличается от стандартного представления или нужна дополнительная логика.
ВЫБОР
КОГДА Таб.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20)
ТОГДА "20 %"
КОГДА Таб.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10)
ТОГДА "10 %"
КОГДА Таб.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.БезНДС)
ТОГДА "Без НДС"
ИНАЧЕ "Не определено"
КОНЕЦ КАК СтавкаНДСТекстомРасчет значений в зависимости от перечисления
Вторая большая группа задач — вычисления, где коэффициент или формула зависят от значения перечисления. Например, сумма НДС рассчитывается по-разному для ставок 20 %, 10 % и «без НДС»: в ветках ТОГДА размещаются выражения Сумма 20 / 120, Сумма 10 / 110 и 0.
Здесь критично следить за типом результата. Если одна ветка возвращает число, а другая — строку, запрос либо завершится ошибкой, либо тип поля станет составным, что усложнит дальнейшую обработку. Все ветки ТОГДА и ИНАЧЕ должны возвращать значения совместимых типов: только числа, только строки или только даты.
Для числовых расчетов полезно явно приводить результат через ВЫРАЗИТЬ(... КАК ЧИСЛО(15, 2)), чтобы гарантировать разрядность и избежать потери копеек при промежуточных делениях. Это особенно важно, когда результат участвует в последующей группировке с суммированием.
- 1Определите поле с перечислением и список значений, которые нужно обработать
- 2Откройте конструктор запроса и добавьте вычисляемое поле
- 3Напишите ВЫБОР КОГДА Поле = ЗНАЧЕНИЕ(Перечисление.Имя.Элемент) ТОГДА результат для каждого значения
- 4Добавьте ветку ИНАЧЕ со значением по умолчанию, чтобы исключить NULL
- 5Проверьте, что все ветки возвращают один тип данных
- 6Выполните запрос в консоли и сверьте результат с данными в режиме предприятия
Фильтрация и группировка по значениям перечисления
«Выбор Когда» используется не только в списке полей, но и для формирования признаков, по которым затем группируются или фильтруются данные. Например, документы можно разбить на «Реализация», «Возврат» и «Прочие» по виду операции и сгруппировать итоги по этому вычисляемому признаку в итоговом запросе или в СКД.
Для простого отбора по одному значению конструкция не нужна: достаточно условия ГДЕ Поле = ЗНАЧЕНИЕ(Перечисление.Имя.Элемент) или параметра-списка с оператором В (&Список). «Выбор Когда» оправдан, когда по разным значениям перечисления нужно применить разную логику или свести несколько значений в одну категорию.
При группировке по вычисляемому полю с «Выбор Когда» в чистом запросе потребуется вложенный запрос: сначала вычисляется признак во внутреннем запросе, затем во внешнем выполняется СГРУППИРОВАТЬ ПО по нему. В СКД это делается проще — вычисляемое поле добавляется в набор ресурсов и группировок через настройки отчета.
Особенности и ограничения конструкции
В языке запросов 1С есть только поисковая форма CASE: условие в каждой ветке пишется полностью, включая имя поля. Сокращенной формы вида «CASE поле WHEN значение» нет, поэтому сравнение повторяется в каждой ветке КОГДА. Это делает текст длиннее, но позволяет комбинировать разные поля и условия в одной конструкции.
Сравнение с NULL внутри «Выбор Когда» работает по-особенному: равенство с NULL никогда не истинно. Если поле может быть не заполнено (например, в необязательном реквизите), проверку делают через Поле ЕСТЬ NULL в отдельной ветке КОГДА, причем ее лучше ставить первой, чтобы она не перекрывалась другими условиями.
Еще одно ограничение — производительность при большом числе веток. Десятки условий «Когда» в поле, вычисляемом для миллионов строк, замедляют запрос. Если значений много и соответствие фиксировано, часто эффективнее завести соответствие в коде, передать его в запрос временной таблицей и соединить с основными данными.
Как выбрать подход
Типичные ошибки и как их проверить
Самая частая ошибка — использование синонима вместо имени элемента в ЗНАЧЕНИЕ(). Запрос при этом не выполнится вообще: конструктор сообщит, что поле не найдено. Ошибка ловится сразу, но только если запрос реально выполняется — в редко используемых ветках кода она может всплыть у пользователя.
Вторая ошибка — отсутствие ветки ИНАЧЕ. Тогда все непредусмотренные значения превращаются в NULL: при суммировании такие строки выпадают из итогов, при соединении — теряются. Признак проблемы: сумма по детальным строкам не сходится с итогом по документу.
Третья группа ошибок связана с типами: смешение строки и числа в ветках, сравнение перечисления со строкой вместо ЗНАЧЕНИЕ(), сравнение с NULL через равенство. Все они диагностируются выполнением запроса в консоли запросов на копии базы с просмотром типа итогового поля.
Как проверить результат
Запрос выполняется без ошибок, поле заполнено
Ошибка «Поле не найдено» или пустая колонка
Каждое значение дает ожидаемый результат
Часть строк ушла в ИНАЧЕ без причины
Суммы сходятся
Расхождение — признак NULL в вычисляемом поле
Единый тип (число или строка)
Составной тип или NULL в части строк
Альтернативы конструкции «Выбор Когда»
Когда значений перечисления много или соответствие должно меняться без доработки конфигурации, «Выбор Когда» заменяют соединением с временной таблицей. В коде формируется таблица значений с колонками «ЗначениеПеречисления» и «Результат», помещается в запрос через ПОМЕСТИТЬ, и основная выборка соединяется с ней левым соединением. Такое решение проще поддерживать, но требует больше кода.
В отчетах на СКД часть задач решается без изменения запроса: вычисляемые поля с собственными выражениями, форматирование полей и пользовательские поля в настройках. Это удобно, когда логика нужна только для представления, а не для расчетов.
Для единичных случаев в коде вне запроса используется обычный оператор Если ... ИначеЕсли или соответствие: СоответствиеСтавок.Получить(СтавкаНДС). Это читабельнее и проще отлаживается, но неприменимо внутри запроса — выбор инструмента зависит от того, где именно нужен результат.
Сравнение подходов
Подходит для 2–10 фиксированных значений; логика хранится в тексте запроса и проверяется при компиляции
Подходит при большом числе значений или когда соответствие задается данными; требует кода для подготовки таблицы
Подходит для оформления представления в отчете без изменения основного запроса
Подходит для логики вне запроса; проще отладка, но нельзя использовать внутри выборки
Что важно запомнить
Перечисление в «Выбор Когда» сравнивается через ЗНАЧЕНИЕ(Перечисление.Имя.Элемент) по имени из конфигуратора. Всегда добавляйте ИНАЧЕ, держите единый тип результата во всех ветках и проверяйте NULL отдельным условием ЕСТЬ NULL. При большом числе значений выносите соответствие во временную таблицу.
Частые вопросы
Можно ли в «Выбор Когда» сравнивать перечисление со строкой?
Нет. Перечисление — ссылочный тип, и сравнение со строкой всегда ложно. Нужно использовать ЗНАЧЕНИЕ(Перечисление.Имя.Элемент), где указывается имя элемента из конфигуратора, а не его синоним.
Что будет, если не указать ветку ИНАЧЕ?
Для всех значений, не попавших ни в одно условие КОГДА, поле получит NULL. Такие строки выпадают из сумм, не соединяются с другими таблицами и могут искажать итоги отчета, поэтому ИНАЧЕ стоит добавлять всегда.
Как обработать ситуацию, когда поле перечисления не заполнено?
Добавьте первой веткой КОГДА Поле ЕСТЬ NULL ТОГДА значение_для_пустого. Сравнение через равенство с NULL не работает — условие никогда не будет истинным.
Можно ли использовать «Выбор Когда» в секции ГДЕ?
Технически да, но для фильтрации это лишнее: проще написать ГДЕ Поле = ЗНАЧЕНИЕ(...) или Поле В (&СписокЗначений). «Выбор Когда» в условиях оправдан редко и ухудшает читаемость запроса.
Почему запрос перестал работать после обновления конфигурации?
Вероятная причина — переименование элемента перечисления, на который ссылается ЗНАЧЕНИЕ(). Имя в запросе должно совпадать с именем в метаданных. После обновлений проверяйте все запросы, где перечисления используются явно.
Как сгруппировать данные по результату «Выбор Когда»?
В обычном запросе — через вложенный запрос: внутренний вычисляет признак, внешний группирует по нему. В СКД достаточно добавить вычисляемое поле и использовать его в группировке настроек отчета.