Разработка и Конфигурация · 12 мин
ВЫБОР КОГДА в условии запроса 1С: практическое руководство
Как использовать конструкцию ВЫБОР КОГДА в запросах 1С: синтаксис, примеры для отчетов, проверка NULL, типичные ошибки и ограничения языка запросов.
Конструкция ВЫБОР КОГДА — это аналог оператора CASE в языке запросов 1С. Она позволяет вернуть разные значения в одном поле выборки в зависимости от условий, не прибегая к постобработке результата в коде и не дублируя запросы. Разработчик пишет одно поле, а платформа сама вычисляет нужное значение для каждой строки.
Чаще всего ВЫБОР КОГДА применяют в трёх сценариях: вывод текстовых представлений вместо технических значений (например, «Оплачен» вместо ссылки на перечисление), формирование расчётных колонок в отчётах на СКД и замена NULL на значение по умолчанию при левых соединениях. Во всех этих случаях конструкция работает на уровне СУБД, поэтому выполняется быстро и не требует обхода выборки.
Важно понимать ограничения: ВЫБОР КОГДА — это выражение поля выборки, а не полноценный условный оператор. Внутри него нельзя выполнять действия, можно только возвращать значения. Также конструкция не заменяет отбор в секции ГДЕ: если нужно отфильтровать строки, ВЫБОР здесь не поможет — для этого существуют другие механизмы, о которых ниже.
Синтаксис конструкции ВЫБОР КОГДА
Полная форма конструкции выглядит так:
ВЫБОР
КОГДА Продажи.Сумма > 100000
ТОГДА "Крупная"
КОГДА Продажи.Сумма > 10000
ТОГДА "Средняя"
ИНАЧЕ "Мелкая"
КОНЕЦ КАК КатегорияСделки
Условия проверяются сверху вниз, и срабатывает первое истинное. Поэтому порядок веток КОГДА имеет значение: если поставить проверку «больше 10000» выше, чем «больше 100000», крупные сделки попадут в категорию «Средняя». Это одна из самых частых логических ошибок при работе с конструкцией.
Ветка ИНАЧЕ необязательна, но без неё для строк, не подошедших ни под одно условие, поле вернёт NULL. В отчётах это выглядит как пустая ячейка, а при последующих сравнениях в коде может дать неожиданные результаты, потому что NULL не равен ни одному значению, включая пустую строку и ноль. Рекомендуется всегда прописывать ИНАЧЕ явно.
Существует и сокращённая форма — поисковая: ВЫБОР Поле КОГДА Значение1 ТОГДА Результат1 ... КОНЕЦ. Она удобна, когда одно и то же поле сравнивается с несколькими конкретными значениями, например статус документа с элементами перечисления.
Типовые сценарии использования
Вывод представлений вместо ссылок и технических значений
Классическая задача — показать пользователю понятный текст вместо булева значения или служебного кода. Например, вместо Истина/Ложь вывести «Да»/«Нет»:
ВЫБОР
КОГДА Контрагенты.ЮрФизЛицо = ЗНАЧЕНИЕ(Перечисление.ЮрФизЛицо.ЮрЛицо)
ТОГДА "Юридическое лицо"
ИНАЧЕ "Физическое лицо"
КОНЕЦ КАК ТипКонтрагента
Такой приём особенно полезен в отчётах на СКД, где нет возможности переопределить вывод поля кодом. Всё форматируется прямо в запросе набора данных.
Замена NULL при соединениях
При левом соединении поля правой таблицы для несовпавших строк содержат NULL. ВЫБОР КОГДА в связке с проверкой ЕСТЬ NULL позволяет подставить осмысленное значение:
ВЫБОР
КОГДА Остатки.КоличествоОстаток ЕСТЬ NULL
ТОГДА 0
ИНАЧЕ Остатки.КоличествоОстаток
КОНЕЦ КАК Остаток
Для этой задачи есть и специальная функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) — она короче и читается легче. ВЫБОР КОГДА оправдан, когда логика сложнее простой подстановки: например, NULL нужно заменить на 0, а отрицательные значения — обнулить.
Расчётные колонки в отчётах
ВЫБОР КОГДА позволяет разложить одну меру по нескольким колонкам — техника, известная как «кросс-таблица вручную»:
СУММА(ВЫБОР
КОГДА Продажи.Менеджер = &Менеджер1
ТОГДА Продажи.Сумма
ИНАЧЕ 0
КОНЕЦ) КАК СуммаМенеджер1
Внутри агрегатной функции ВЫБОР вычисляется для каждой строки до группировки, поэтому сумма получается корректной. Это рабочий способ построить сводный отчёт без настройки группировок колонок в СКД.
ВЫБОР КОГДА в секции ГДЕ и условиях соединения
Конструкцию можно использовать не только в списке полей, но и в секции ГДЕ — для формирования сложных отборов. Например, отобрать документы по разным критериям в зависимости от параметра:
ГДЕ
ВЫБОР
КОГДА &ТолькоКрупные
ТОГДА Продажи.Сумма > 100000
ИНАЧЕ ИСТИНА
КОНЕЦ
Такой приём позволяет писать один запрос вместо двух вариантов с условным формированием текста. Однако у него есть цена: оптимизатор СУБД хуже строит план для параметризованных условий, и на больших таблицах запрос может работать медленнее, чем два специализированных. Если таблица содержит миллионы записей, сравните производительность обоих подходов на реальных данных.
В условии соединения ВЫБОР КОГДА применяется редко, но допустим — например, когда ключ связи зависит от вида документа. Здесь действует то же предупреждение: соединения по вычисляемым выражениям обычно не используют индексы, что критично для больших регистров.
ВЫБОР КОГДА в СКД и динамических списках
В схеме компоновки данных конструкция работает в тексте запроса набора данных без ограничений — это стандартный способ добавить вычисляемые колонки. Дополнительно СКД предлагает собственные средства: вычисляемые поля и ресурсы с выражениями. Выбор между ними зависит от задачи.
Если значение можно вычислить в запросе — вычисляйте в запросе: это быстрее и позволяет использовать поле в отборах и группировках на уровне СУБД. Вычисляемые поля СКД оправданы, когда нужны функции языка выражений компоновки или значение зависит от уже сгруппированных данных.
В динамических списках ВЫБОР КОГДА в произвольном запросе также работает, но есть нюанс: поля, вычисленные через ВЫБОР, недоступны для отбора пользователем стандартными средствами, если не описаны корректно, а сортировка по ним может быть медленной. Для динамических списков предпочтительнее выводить реальные поля таблиц, а представления получать через соединения с перечислениями или справочниками.
Сравнение вариантов
Подходит для расчётных колонок, замены NULL, представлений. Работает на уровне СУБД, быстро. Ограничение: только возврат значений, сложные условия могут замедлять отбор.
Короткая замена NULL на значение по умолчанию. Только один сценарий — подстановка вместо NULL, без дополнительной логики.
Когда нужны функции языка выражений СКД или расчёт после группировки. Не участвует в отборах на уровне СУБД.
Крайний вариант: обход выборки медленнее и требует больше кода, но даёт полную свободу логики.
Типичные ошибки и как их избежать
Первая ошибка — неправильный порядок условий. Поскольку проверки идут сверху вниз и срабатывает первая истинная, более общие условия нужно ставить ниже более частных. Перед сдачей запроса проверьте граничные значения: ровно 10000, ровно 100000, ноль, отрицательные числа.
Вторая ошибка — забыт ИНАЧЕ. Поле молча возвращает NULL для части строк, что в отчёте выглядит как пропуски, а в СКД может сломать итоги, если по этому полю строится группировка. Всегда задавайте значение по умолчанию, даже если кажется, что все случаи покрыты условиями.
Третья ошибка — смешение типов в ветках. Если ТОГДА возвращает число, а ИНАЧЕ — строку «нет данных», сортировка и сравнения по этому полю будут вести себя непредсказуемо. Для смешанного вывода приводите числа к строке явно через ПРЕДСТАВЛЕНИЕ или формируйте два отдельных поля.
Четвёртая ошибка — попытка использовать ВЫБОР КОГДА вместо отбора. Разработчик выводит колонку «Подходит/Не подходит» вместо того, чтобы отфильтровать строки в ГДЕ. В результате выборка тащит лишние данные, а отчёт перегружен. Правило простое: ВЫБОР формирует значения, ГДЕ — отбирает строки.
Проверка результата и отладка
Отлаживать ВЫБОР КОГДА удобнее всего в консоли запросов: выполните запрос на тестовых данных и проверьте, что каждая ветка срабатывает на ожидаемых строках. Если в данных нет строк для какой-то ветки, создайте тестовый документ или временно ослабьте условия, чтобы увидеть все варианты.
Полезный приём — вывести рядом с вычисляемым полем исходные поля, участвующие в условии. Так сразу видно, почему строка получила то или иное значение. После проверки вспомогательные поля убирают.
Для запросов с группировкой проверяйте, что ВЫБОР стоит на правильном уровне: если условие зависит от поля, не входящего в группировку, и не обёрнуто в агрегатную функцию, конструктор запросов выдаст ошибку. Либо добавьте поле в СГРУППИРОВАТЬ ПО, либо поместите ВЫБОР внутрь СУММА/МАКСИМУМ.
Как проверить результат
Каждая ветка КОГДА срабатывает на ожидаемых строках, пустых значений нет
Часть строк содержит NULL или попадает не в ту категорию
Значения ровно на пороге попадают в правильную ветку
Пограничные строки классифицируются неверно — нарушен порядок условий
Все строки одного типа, сортировка и группировка работают
Смешанные типы, ошибки компоновки в СКД
Запрос выполняется за приемлемое время на рабочем объёме
Резкое замедление после добавления ВЫБОР в ГДЕ или соединение
Альтернативы и границы применимости
Не каждая задача требует ВЫБОР КОГДА. Для простой замены NULL короче функция ЕСТЬNULL. Для вывода представления ссылочного поля достаточно функции ПРЕДСТАВЛЕНИЕ. Для отбора по сложным условиям правильнее использовать ГДЕ с логическими операторами И, ИЛИ и скобками.
Если логика вычисления поля становится громоздкой — десятки веток КОГДА или вложенные ВЫБОР внутри ВЫБОР — это признак того, что логику стоит вынести в данные: например, завести дополнительный реквизит, регистр сведений с соответствиями или перечисление. Запрос с соединением к такой таблице читается и поддерживается проще, чем простыня условий.
Граница самостоятельной работы проходит там, где начинается оптимизация производительности на больших объёмах: если запрос с ВЫБОР КОГДА в отборе тормозит, нужен анализ плана запроса и, возможно, пересмотр структуры индексов — это задача для опытного разработчика или администратора СУБД.
Что важно запомнить
ВЫБОР КОГДА — инструмент для вычисляемых полей: представлений, расчётных колонок, замены NULL. Соблюдайте порядок условий, всегда пишите ИНАЧЕ, не смешивайте типы и не используйте конструкцию вместо отбора в ГДЕ. Для простых случаев есть короткие альтернативы: ЕСТЬNULL и ПРЕДСТАВЛЕНИЕ.
Частые вопросы
Можно ли использовать ВЫБОР КОГДА внутри СУММА или другой агрегатной функции?
Да, это стандартный приём: СУММА(ВЫБОР КОГДА условие ТОГДА Сумма ИНАЧЕ 0 КОНЕЦ). ВЫБОР вычисляется для каждой строки до группировки, поэтому итог получается корректным. Обратная ситуация — ВЫБОР снаружи агрегата по негруппированному полю — вызовет ошибку.
Как внутри КОГДА проверить значение на NULL?
Через конструкцию «Поле ЕСТЬ NULL»: КОГДА Таблица.Поле ЕСТЬ NULL ТОГДА ... Сравнение через знак равенства не сработает — NULL не равен никакому значению, включая сам себя, поэтому условие никогда не станет истинным.
Чем ВЫБОР КОГДА отличается от функции ЕСТЬNULL?
ЕСТЬNULL(Поле, Значение) — сокращённая запись для одного случая: подставить значение вместо NULL. ВЫБОР КОГДА универсальнее: позволяет проверять любые условия и возвращать разные результаты. Если задача — только замена NULL, используйте ЕСТЬNULL, это короче и понятнее при чтении.
Можно ли вкладывать один ВЫБОР КОГДА внутрь другого?
Технически да, вложенность допустима, и запрос выполнится. Но читаемость резко падает: уже два уровня вложенности сложно отлаживать. Если возникла потребность во вложенных ВЫБОР, рассмотрите вариант с выносом логики в отдельную таблицу соответствий и соединением с ней.
Почему запрос с ВЫБОР КОГДА в секции ГДЕ стал работать медленно?
Параметризованные условия через ВЫБОР мешают оптимизатору СУБД использовать индексы — план строится «на все случаи». На больших таблицах эффективнее сформировать два отдельных текста запроса в коде и выполнить нужный, либо переписать условие через логические операторы И/ИЛИ без ВЫБОР.
Работает ли ВЫБОР КОГДА в динамическом списке с произвольным запросом?
Да, конструкция работает. Ограничения касаются удобства использования: сортировка и отбор по вычисленному полю могут быть медленными или недоступными. Для динамических списков предпочтительнее выводить реальные поля таблиц, а текстовые представления получать через соединения.