Разработка и Конфигурация · 13 мин
ВЫБОР КОГДА с перечислением в запросе 1С: синтаксис, примеры и ошибки
Как использовать ВЫБОР КОГДА с перечислением в запросе 1С: синтаксис, сравнение со значением перечисления, проверка пустых ссылок, типовые ошибки и примеры кода.
Конструкция ВЫБОР КОГДА в языке запросов 1С — это аналог оператора CASE в SQL. Она позволяет вернуть разные значения в зависимости от условий, и одна из самых частых задач — сопоставить поле типа «ПеречислениеСсылка» с конкретным значением и вывести текст, число или другую ссылку. Например, в отчёте по документам нужно показать «Оплачен» или «Не оплачен» вместо служебного значения перечисления «СтатусОплаты».
Главная сложность при работе с перечислениями в запросе — правильное обращение к значению. В отличие от встроенного языка, где пишут Перечисления.СтавкиНДС.НДС20, в тексте запроса используется функция ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20) — без буквы «и» после «Перечисление» и через конструкцию ЗНАЧЕНИЕ. Ошибка в этой детали — самая частая причина того, что запрос не выполняется или возвращает пустой результат.
Ниже разобраны синтаксис ВЫБОР КОГДА, способы сравнения с перечислением, работа с пустыми ссылками, альтернатива через СОЕДИНЕНИЕ, типичные ошибки и способы проверить результат до вывода в отчёт.
Синтаксис ВЫБОР КОГДА в языке запросов 1С
Общая форма конструкции выглядит так: после ключевого слова ВЫБОР перечисляются ветки КОГДА с условием и результатом через ТОГДА, в конце — необязательная ветка ИНАЧЕ и обязательное слово КОНЕЦ. Условий может быть сколько угодно, они проверяются сверху вниз, и срабатывает первая истинная ветка.
ВЫБОР
КОГДА Документ.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокумента.Проведен)
ТОГДА "Проведён"
КОГДА Документ.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокумента.Отклонен)
ТОГДА "Отклонён"
ИНАЧЕ "В работе"
КОНЕЦ КАК СтатусТекстом
Важные правила синтаксиса. Все возвращаемые значения в ветках ТОГДА и ИНАЧЕ должны быть совместимы по типу: нельзя в одной ветке вернуть строку, а в другой — число или ссылку, иначе получите ошибку несовместимости типов или непредсказуемый результат в СКД. Если ветка ИНАЧЕ отсутствует и ни одно условие не сработало, поле получит значение NULL — это нужно учитывать при последующей группировке и соединениях.
Псевдоним поля задаётся через КАК после слова КОНЕЦ. Без псевдонима обратиться к вычисляемой колонке в коде или настройках СКД будет затруднительно.
Как правильно сослаться на значение перечисления
Ключевое отличие запроса от встроенного языка — написание. В модуле вы обращаетесь к менеджеру Перечисления (множественное число), а в тексте запроса — к типу Перечисление (единственное число) внутри функции ЗНАЧЕНИЕ. Полная форма: ЗНАЧЕНИЕ(Перечисление.ИмяПеречисления.ИмяЗначения).
ГДЕ
Товары.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20)
Имя значения в запросе — это имя, заданное в конфигураторе, а не синоним, который видит пользователь. Если значение называется «НДС20», а синоним — «20%», в запросе пишется именно «НДС20». Посмотреть имя можно в конфигураторе: откройте перечисление в дереве метаданных и проверьте колонку «Имя» у нужного значения.
Альтернатива — передать значение параметром: ГДЕ Товары.СтавкаНДС = &Ставка, а в коде установить Запрос.УстановитьПараметр("Ставка", Перечисления.СтавкиНДС.НДС20). Параметр удобнее, когда значение выбирает пользователь или оно вычисляется в коде, а ЗНАЧЕНИЕ — когда условие жёстко зашито в текст запроса. Параметр также делает запрос устойчивым к переименованию значений перечисления в конфигурации.
ЗНАЧЕНИЕ или параметр
Подходит для фиксированных условий внутри текста запроса. Ограничение: при переименовании значения в конфигураторе запрос перестанет работать.
Подходит, когда значение приходит из кода или от пользователя. Запрос не зависит от имён значений перечисления, но требует установки параметра перед выполнением.
Сравнение поля с перечислением внутри ВЫБОР КОГДА
Самый частый сценарий — преобразовать значение перечисления в понятную строку или в другое представление для отчёта. Условие в ветке КОГДА — обычное сравнение поля через знак равенства со значением перечисления.
ВЫБОР
КОГДА Реализация.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийРеализация.Товары)
ТОГДА "Продажа товаров"
КОГДА Реализация.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийРеализация.Услуги)
ТОГДА "Продажа услуг"
ИНАЧЕ "Прочее"
КОНЕЦ КАК ОписаниеОперации
В условии допустимы и другие операторы: неравенство <>, проверка В ИЕРАРХИИ (для перечислений не применяется, так как они не иерархические), логические И и ИЛИ для комбинации нескольких условий. Например, можно объединить проверку перечисления с проверкой суммы документа в одной ветке.
Учтите порядок веток: если условия пересекаются, сработает первая по тексту. Поэтому более частные условия ставьте выше, а общие — ниже. Ветка ИНАЧЕ в конце страхует от появления NULL при добавлении в конфигурацию новых значений перечисления, которые ваш запрос ещё не обрабатывает.
- 1Откройте перечисление в конфигураторе и выпишите точные имена нужных значений (колонка «Имя», не синоним).
- 2Сформируйте текст запроса: ВЫБОР КОГДА Поле = ЗНАЧЕНИЕ(Перечисление.Имя.Значение) ТОГДА ... ИНАЧЕ ... КОНЕЦ КАК Псевдоним.
- 3Убедитесь, что все ветки ТОГДА и ИНАЧЕ возвращают значения одного типа.
- 4Выполните запрос в консоли запросов на тестовой копии базы и проверьте, что каждая ветка срабатывает на реальных данных.
- 5Перенесите проверенный текст в модуль или схему СКД.
Проверка пустой ссылки и незаполненного значения
Если реквизит типа «ПеречислениеСсылка» не заполнен, он хранит пустую ссылку, а не NULL. Поэтому проверка Поле ЕСТЬ NULL такой случай не поймает. Пустую ссылку сравнивают с пустым значением перечисления: ЗНАЧЕНИЕ(Перечисление.ИмяПеречисления.ПустаяСсылка).
ВЫБОР
КОГДА Документ.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокумента.ПустаяСсылка)
ТОГДА "Статус не задан"
КОГДА Документ.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокумента.Завершен)
ТОГДА "Завершён"
ИНАЧЕ "В работе"
КОНЕЦ КАК СтатусТекстом
NULL в поле типа перечисления появляется только в результате соединений таблиц — например, при ЛЕВОМ СОЕДИНЕНИИ, когда в правой таблице нет подходящей строки. В этом случае проверка Поле ЕСТЬ NULL обязательна, и её стоит ставить первой веткой, потому что сравнение NULL с чем-либо через равенство всегда даёт ложь.
Рабочая последовательность веток для поля из соединения: сначала КОГДА Поле ЕСТЬ NULL ТОГДА ..., затем проверка пустой ссылки, затем конкретные значения, в конце ИНАЧЕ. Такой порядок гарантирует, что ни одна ситуация не выпадет в NULL результата.
Альтернатива: СОЕДИНЕНИЕ с таблицей перечисления
Если нужно не сопоставить значения вручную, а просто вывести представление перечисления или отобрать по нему, можно соединиться с виртуальной таблицей перечисления: Перечисление.ИмяПеречисления. У неё есть поля Ссылка, Порядок и Представление.
ВЫБРАТЬ
Документы.Ссылка,
Статусы.Представление КАК СтатусПредставление
ИЗ
Документ.ЗаказКлиента КАК Документы
ЛЕВОЕ СОЕДИНЕНИЕ Перечисление.СтатусыЗаказа КАК Статусы
ПО Документы.Статус = Статусы.Ссылка
Этот способ удобен, когда нужно вывести все возможные значения перечисления (даже те, которых нет в документах) — для этого перечисление ставят первой таблицей и делают ЛЕВОЕ СОЕДИНЕНИЕ документов к нему. Также поле Порядок позволяет сортировать по порядку значений в конфигураторе, а не по алфавиту представления.
Однако для логики «если статус такой-то, то вывести такой-то текст» соединение не заменяет ВЫБОР КОГДА: произвольные соответствия, отличные от синонимов, всё равно задаются только ветками КОГДА.
Типичные ошибки и как их найти
Первая и самая массовая ошибка — написать Перечисления.Имя.Значение (во множественном числе) или забыть обёртку ЗНАЧЕНИЕ. Конструктор запросов при проверке выдаст сообщение о неверном поле или типе. Вторая ошибка — использовать синоним значения вместо имени: запрос выполнится с ошибкой «Поле не найдено», потому что платформа ищет именно имя метаданных.
Третья группа ошибок связана с типами результата: в одной ветке строка, в другой — число или ссылка. В простом запросе это иногда проходит незамеченным, но в СКД или при помещении результата во временную таблицу приводит к ошибкам приведения типов. Четвёртая ошибка — забыть ИНАЧЕ и получить NULL, который затем «съедает» строки при внутреннем соединении по этому полю или ломает итоги группировки.
Проверять результат удобно в консоли запросов: отберите несколько документов с известными статусами, выполните запрос и сверьте, что каждая ветка сработала. Если какая-то ветка никогда не срабатывает на реальных данных — либо условие написано неверно, либо таких значений в базе нет, и ветку стоит перепроверить по конфигуратору.
Проверка результата и FAQ
После написания запроса выполните три контрольные проверки. Первая — полнота: убедитесь, что в результате нет NULL в вычисляемой колонке, если вы их не ожидали. Вторая — корректность: возьмите 3–5 документов с разными значениями перечисления и убедитесь, что каждому соответствует правильная ветка. Третья — устойчивость: проверьте документ с незаполненным реквизитом и документ, попавший в выборку через соединение без пары.
Если запрос используется в отчёте на СКД, дополнительно проверьте итоги: NULL в поле группировки создаёт отдельную строку итога с пустым значением, что часто выглядит как «лишняя строка» в отчёте. Лечится веткой ИНАЧЕ или отбором в настройках.
Как проверить результат
Все строки заполнены ожидаемыми значениями веток
Есть NULL или пустые значения там, где их не должно быть
Попадает в ветку проверки ПустаяСсылка или ИНАЧЕ
Строка теряется или получает неверное значение
Группировки соответствуют заданным веткам
Появилась отдельная группа с пустым значением
Можно ли сравнивать перечисление со строкой в запросе 1С?
Напрямую нет: поле типа ПеречислениеСсылка нельзя сравнить со строкой, это разные типы. Если нужно сопоставить с текстом, сравнивайте поле с ЗНАЧЕНИЕ(Перечисление...), а строку возвращайте в ветке ТОГДА. Либо получите представление через соединение с таблицей перечисления и сравнивайте уже поле Представление, но это медленнее и менее надёжно.
Чем ВЫБОР КОГДА отличается от функции ЕСТЬNULL?
ЕСТЬNULL(Поле, Значение) — частный случай: она заменяет только NULL на заданное значение. ВЫБОР КОГДА универсальнее и позволяет проверять любые условия, включая сравнение с конкретными значениями перечисления, пустой ссылкой и комбинации условий. Для простой подмены NULL используйте ЕСТЬNULL — она короче и читабельнее.
Что будет, если значение перечисления переименуют в конфигураторе?
Запрос с ЗНАЧЕНИЕ(Перечисление.Имя.СтароеИмя) перестанет выполняться с ошибкой «Поле не найдено». Платформа при реструктуризации не отслеживает тексты запросов в модулях. Чтобы снизить риск, передавайте значение параметром из кода — там переименование отслеживается рефакторингом, либо после переименования выполните поиск старого имени по всем модулям конфигурации.
Можно ли в ТОГДА вернуть ссылку на другое перечисление или справочник?
Да, если во всех ветках возвращается один и тот же тип. Например, все ветки возвращают значения одного перечисления или ссылки одного справочника. Смешивать ссылку и строку нельзя — получите ошибку несовместимости типов при выполнении или в СКД. Если нужны разные типы, приводите всё к строке через ПРЕДСТАВЛЕНИЕ.
Как вывести значение перечисления как число или порядок?
Числового «кода» у значений перечисления нет, но есть поле Порядок в таблице перечисления. Соединитесь с Перечисление.ИмяПеречисления по ссылке и выберите поле Порядок — получите порядковый номер значения, заданный в конфигураторе. Его же удобно использовать для сортировки вместо алфавитного порядка представлений.
Работает ли ВЫБОР КОГДА в условии ГДЕ или только в списке полей?
ВЫБОР КОГДА допустим в списке выбираемых полей, в условии ГДЕ, в ИМЕЮЩИЕ и в условиях соединения. Однако в ГДЕ проще и быстрее писать прямое сравнение: ГДЕ Поле = ЗНАЧЕНИЕ(...). ВЫБОР в отборе оправдан только для сложной логики, которую нельзя выразить простыми условиями с И и ИЛИ.
Что важно запомнить
Значение перечисления в запросе указывается через ЗНАЧЕНИЕ(Перечисление.Имя.Значение) — в единственном числе и по имени из конфигуратора. В ВЫБОР КОГДА все ветки должны возвращать один тип, ветка ИНАЧЕ защищает от NULL, а незаполненный реквизит проверяется сравнением с ПустаяСсылка. Перед использованием в отчёте запрос проверяют в консоли на документах с известными статусами.