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