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