К статье
Практический материал

Разработка и Конфигурация · 10 мин

ВЫБОР КОГДА и ВЫРАЗИТЬ в запросах 1С: как применять правильно

Конструкция ВЫБОР КОГДА ТОГДА КОНЕЦ и функция ВЫРАЗИТЬ в языке запросов 1С: синтаксис, примеры, типовые ошибки и способы проверки результата.

Конструкция ВЫБОР ... КОГДА ... ТОГДА ... КОНЕЦ — аналог оператора CASE в языке запросов 1С. Она позволяет вернуть разные значения в одном поле в зависимости от условий, не создавая несколько запросов и не обрабатывая результат в коде. Функция ВЫРАЗИТЬ решает другую задачу — приводит значение к конкретному типу, что критично для составных полей, соединений и сравнений.

Обе конструкции часто используются вместе: например, когда в ВЫБОР нужно подставить значение составного типа, его сначала приводят через ВЫРАЗИТЬ, иначе запрос вернёт ошибку несовместимости типов. Понимание того, как они взаимодействуют, избавляет от большинства ошибок «Ошибка в выражении» и «Несовместимые типы».

Материал рассчитан на разработчиков и внедренцев, которые пишут запросы в консоли запросов, СКД или программно. Все примеры применимы к типовым конфигурациям на платформе 8.3 и самописным решениям.

Синтаксис ВЫБОР КОГДА: полная и краткая формы

Полная форма конструкции выглядит так:

ВЫБОР

КОГДА Продажи.Сумма > 100000 ТОГДА "Крупная"

КОГДА Продажи.Сумма > 10000 ТОГДА "Средняя"

ИНАЧЕ "Мелкая"

КОНЕЦ КАК КатегорияПродажи

Условия проверяются сверху вниз, срабатывает первое истинное. Если ни одно условие не выполнилось и ветки ИНАЧЕ нет — поле получит значение NULL, что часто становится источником скрытых ошибок при последующих сравнениях и группировках.

Существует и краткая форма для сравнения одного выражения с несколькими значениями:

ВЫБОР Заказ.Статус

КОГДА ЗНАЧЕНИЕ(Перечисление.Статусы.Новый) ТОГДА 1

КОГДА ЗНАЧЕНИЕ(Перечисление.Статусы.Оплачен) ТОГДА 2

ИНАЧЕ 0

КОНЕЦ КАК ПорядокСортировки

Краткая форма поддерживает только проверку на равенство. Для диапазонов, сравнений «больше/меньше» и составных условий используйте полную форму.

Типовые сценарии применения ВЫБОР

Расчётное поле в отчёте

Самая частая задача — добавить в выборку вычисляемую колонку: признак просрочки, категорию клиента, текстовый статус. Пример с датами:

ВЫБОР

КОГДА Долг.ДатаОплаты < &ТекущаяДата

ТОГДА "Просрочен"

ИНАЧЕ "В срок"

КОНЕЦ КАК СостояниеДолга

Замена NULL на значение по умолчанию

При левых соединениях отсутствующие записи дают NULL. ВЫБОР с проверкой «ЕСТЬ NULL» заменяет их на рабочее значение:

ВЫБОР

КОГДА Остатки.Количество ЕСТЬ NULL ТОГДА 0

ИНАЧЕ Остатки.Количество

КОНЕЦ КАК Остаток

Для простой подмены NULL короче использовать встроенную функцию ЕСТЬNULL(Остатки.Количество, 0) — она читается легче и работает быстрее при анализе запроса.

Сортировка по произвольному правилу

Через ВЫБОР можно задать числовой вес каждому значению и отсортировать результаты не по алфавиту, а по бизнес-логике — например, сначала «В работе», потом «Новые», потом «Закрытые». Поле с весом добавляют в секцию УПОРЯДОЧИТЬ ПО, при необходимости скрыв его из выборки в СКД.

Как добавить ВЫБОР в запрос без ошибок
  1. 1
    Определите, какие значения должно принимать поле, и приведите их к одному типу
  2. 2
    Запишите условия от частного к общему — первое истинное условие прерывает проверку
  3. 3
    Добавьте ветку ИНАЧЕ, чтобы исключить NULL в результате
  4. 4
    Выполните запрос в консоли и проверьте тип итогового поля и значения на границах условий

Функция ВЫРАЗИТЬ: зачем и когда приводить типы

ВЫРАЗИТЬ(Значение КАК Тип) сообщает запросу, что поле нужно трактовать как конкретный тип: ВЫРАЗИТЬ(Реквизит КАК Справочник.Номенклатура), ВЫРАЗИТЬ(Комментарий КАК Строка(100)), ВЫРАЗИТЬ(Сумма КАК Число(15,2)).

Основные ситуации, где без ВЫРАЗИТЬ не обойтись:

  • Составные поля. Если реквизит может хранить несколько типов (например, «Контрагент» — справочник контрагентов или партнёров), обращение к реквизиту конкретного типа без приведения вернёт NULL или ошибку. После ВЫРАЗИТЬ точечный доступ к полям работает корректно.
  • Строки неограниченной длины. Группировка, соединение и сравнение по неограниченной строке запрещены. ВЫРАЗИТЬ(Поле КАК Строка(200)) обрезает значение до фиксированной длины и снимает ограничение.
  • Соединения и сравнения. Сравнение значений разных типов в условии соединения может привести к неэффективному плану запроса или ошибке. Приведение обеих сторон к одному типу решает проблему.
  • Поля ВЫБОР. Когда в разных ветках ТОГДА возвращаются ссылки разных справочников, итоговый тип поля становится составным; ВЫРАЗИТЬ вокруг всей конструкции фиксирует нужный тип.

Важно понимать: ВЫРАЗИТЬ не преобразует данные физически, а лишь указывает платформе, как интерпретировать значение. Если фактическое значение не соответствует указанному типу, результатом будет NULL, а не ошибка — это нужно учитывать при проверках.

bsl
ВЫБОР
    КОГДА Рег.Плательщик ССЫЛКА Справочник.Контрагенты
        ТОГДА ВЫРАЗИТЬ(Рег.Плательщик КАК Справочник.Контрагенты).ИНН
    ИНАЧЕ ""
КОНЕЦ КАК ИННПлательщика

Совместное использование ВЫБОР и ВЫРАЗИТЬ

Классическая связка: в зависимости от типа составного поля вернуть разные реквизиты. Здесь ВЫБОР проверяет тип через оператор ССЫЛКА, а ВЫРАЗИТЬ открывает доступ к полям конкретного справочника:

ВЫБОР

КОГДА Док.Контрагент ССЫЛКА Справочник.Организации

ТОГДА ВЫРАЗИТЬ(Док.Контрагент КАК Справочник.Организации).Наименование

КОГДА Док.Контрагент ССЫЛКА Справочник.ФизическиеЛица

ТОГДА ВЫРАЗИТЬ(Док.Контрагент КАК Справочник.ФизическиеЛица).ФИО

ИНАЧЕ ""

КОНЕЦ КАК ПредставлениеКонтрагента

Обратный порядок тоже встречается: ВЫРАЗИТЬ применяется к результату всего ВЫБОР, чтобы зафиксировать тип поля для последующей группировки или соединения. Например, ВЫРАЗИТЬ(ВЫБОР ... КОНЕЦ КАК Строка(50)).

При работе в СКД помните, что тип поля вычисляется на этапе компоновки. Если ветки ВЫБОР возвращают разные ссылочные типы, отбор по такому полю в настройках отчёта может работать некорректно — явное приведение типа снимает проблему.

Если после добавления ВЫРАЗИТЬ поле внезапно стало пустым, почти всегда причина в том, что фактические значения не совпадают с указанным типом. Проверьте состав типов поля в конфигураторе и добавьте ветку с проверкой через ССЫЛКА.
ПЗ
Практическое замечание

Производительность: где ВЫБОР и ВЫРАЗИТЬ тормозят запрос

Сам по себе ВЫБОР в списке полей выборки дёшев — он вычисляется построчно и не меняет план запроса. Проблемы начинаются, когда конструкции попадают в условия соединений и отборов:

  • ВЫБОР или ВЫРАЗИТЬ в условии соединения мешает СУБД использовать индексы — соединение превращается в перебор. Решение: привести типы заранее во временной таблице и соединяться по уже подготовленному полю.
  • ВЫРАЗИТЬ по строке большой длины в виртуальных таблицах увеличивает объём обрабатываемых данных. Ограничивайте длину разумным минимумом, а не «с запасом» в 1000 символов.
  • Вложенные ВЫБОР внутри ВЫБОР (3–4 уровня) ухудшают читаемость и усложняют оптимизацию. Часто их можно заменить соединением с небольшой таблицей соответствий.

Проверить влияние на производительность можно, сравнив время выполнения запроса до и после изменения на реальных объёмах данных. На маленькой тестовой базе разница может быть незаметна, а на рабочей — критичной.

Частые ошибки и способы их диагностики

Большинство проблем с этими конструкциями проявляются либо сразу ошибкой выполнения, либо тихим появлением NULL и пустых строк в отчётах.

Типичные ошибки
01
Нет ветки ИНАЧЕ — при несрабатывании условий поле становится NULL и ломает сортировку, группировку и итоги
02
Разные типы в ветках ТОГДА — ошибка выполнения или составной тип поля, с которым не работают отборы в СКД
03
ВЫРАЗИТЬ к несуществующему типу значения — поле молча заполняется NULL, данные 'пропадают' из отчёта
04
Сравнение строки неограниченной длины без приведения — ошибка запроса на этапе выполнения
05
ВЫБОР в условии соединения — резкое падение производительности на больших таблицах

Диагностика начинается с консоли запросов: выполните запрос, откройте результат и проверьте тип колонки и значения на границах условий. Если поле пустое там, где ожидались данные, — первым делом смотрите на соответствие типов в ВЫРАЗИТЬ и наличие ИНАЧЕ в ВЫБОР.

Контрольные точки

Как проверить результат

Тип итогового поля
Норма

Один ожидаемый тип во всех строках

Тревожный признак

Составной тип или NULL в части строк

Значения на границах условий
Норма

Граничные значения попадают в нужную ветку

Тревожный признак

Значение, равное порогу, уходит не туда

Заполненность поля после ВЫРАЗИТЬ
Норма

Данные присутствуют

Тревожный признак

Пустые значения там, где в источнике они есть

FAQ

Чем ВЫБОР отличается от ЕСТЬNULL?

ЕСТЬNULL(Поле, Значение) — частный случай: подменяет только NULL. ВЫБОР универсальнее и позволяет проверять любые условия, включая «ЕСТЬ NULL». Если задача — просто заменить NULL, используйте ЕСТЬNULL: запись короче и читается легче.

Можно ли использовать ВЫБОР в секции ГДЕ (отборе)?

Технически да, но делать этого не стоит: условие не сможет использовать индексы, и отбор будет выполняться полным перебором. Лучше переформулировать условие через логические И/ИЛИ или подготовить данные во временной таблице.

Почему после ВЫРАЗИТЬ поле стало пустым?

Значения в поле не соответствуют указанному типу — например, вы привели поле к Справочник.Номенклатура, а там хранятся ссылки на другой справочник. ВЫРАЗИТЬ не выдаёт ошибку, а возвращает NULL. Проверьте состав типов реквизита в конфигураторе.

Как сравнить строку неограниченной длины в запросе?

Приведите её через ВЫРАЗИТЬ(Поле КАК Строка(N)), где N — достаточная для ваших данных длина. Учтите, что значения длиннее N будут обрезаны, и сравнение будет идти по усечённому значению.

Работает ли ВЫБОР в СКД так же, как в обычном запросе?

Да, синтаксис идентичен, но в СКД дополнительно важен тип итогового поля: от составного типа могут некорректно работать отборы и группировки в настройках отчёта. Фиксируйте тип через ВЫРАЗИТЬ вокруг всей конструкции.

Что быстрее: многоуровневый ВЫБОР или соединение с таблицей соответствий?

При двух-трёх условиях ВЫБОР проще и не уступает по скорости. Когда вариантов много или они часто меняются, соединение с таблицей соответствий (значений или справочником) удобнее в сопровождении и обычно эффективнее.

Итог

Что важно запомнить

ВЫБОР КОГДА возвращает значение по условию: всегда добавляйте ИНАЧЕ и держите один тип во всех ветках. ВЫРАЗИТЬ приводит значение к типу и необходим для составных полей, неограниченных строк и доступа к реквизитам конкретного типа. Обе конструкции держите вне условий соединений, а результат проверяйте в консоли запросов на граничных значениях.