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