Как правильно использовать конструкцию ВЫБОР КОГДА в запросах 1С?

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

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

Основы синтаксиса и типичные ошибки

Рассмотрим стандартную структуру оператора выбора. Проблема, с которой часто сталкиваются начинающие разработчики — это ошибка ожидания выражения или закрывающей скобки. Часто это связано с неверным использованием псевдонимов внутри условий или неправильным порядком операторов. При возникновении сложностей с синтаксисом можно воспользоваться инструментом для поиска ошибок в текстах запросов.

Проанализируем пример корректного написания конструкции для получения контрагента из различных видов документов оприходования:


ВЫБОР
    КОГДА ПартииТоваровНаСкладахОстатки.ДокументОприходования ССЫЛКА Документ.ПоступлениеТоваровУслуг
        ТОГДА ВЫРАЗИТЬ(ПартииТоваровНаСкладахОстатки.ДокументОприходования КАК Документ.ПоступлениеТоваровУслуг).Контрагент
    КОГДА ПартииТоваровНаСкладахОстатки.ДокументОприходования ССЫЛКА Документ.ПоступлениеТоваровУслугВНТТ
        ТОГДА ВЫРАЗИТЬ(ПартииТоваровНаСкладахОстатки.ДокументОприходования КАК Документ.ПоступлениеТоваровУслугВНТТ).Контрагент
    ИНАЧЕ НЕОПРЕДЕЛЕНО
КОНЕЦ КАК Поставщик

Важно обратить внимание на следующие моменты: во-первых, псевдоним через ключевое слово КАК присваивается только один раз в самом конце, после закрывающего слова КОНЕЦ. Во-вторых, не рекомендуется использовать сложные составные псевдонимы типа Номенклатура.ОсновнойПоставщик, лучше ограничиваться простыми именами полей.

Работа с составными типами данных и ВЫРАЗИТЬ

Разберем ситуацию, когда реквизит имеет составной тип данных (например, ДокументОприходования может быть ссылкой на разные виды документов). Если мы попытаемся обратиться к его реквизиту (например, Контрагент) напрямую через точку, система может выполнить неявное левое соединение со всеми таблицами, входящими в этот тип, что негативно скажется на производительности. Для автоматического выявления таких проблем в коде запросов можно использовать обработку для проверки разыменований полей составного типа.

Чтобы избежать этого и обеспечить корректную типизацию, мы используем функцию ВЫРАЗИТЬ. Это позволяет системе точно знать, из какой таблицы нужно извлечь данные. Посмотрим на этот прием в контексте реального запроса:


ВЫБРАТЬ
    ТоварыОстатки.Номенклатура,
    ВЫБОР
        КОГДА ПартииОстатки.ДокументОприходования ССЫЛКА Документ.ПоступлениеТоваровУслуг
            ТОГДА ВЫРАЗИТЬ(ПартииОстатки.ДокументОприходования КАК Документ.ПоступлениеТоваровУслуг).Контрагент
        ИНАЧЕ НЕОПРЕДЕЛЕНО
    КОНЕЦ КАК Поставщик
ИЗ
    РегистрНакопления.ТоварыВНТТ.Остатки КАК ТоварыОстатки
...

Сложные условия и логические ветвления

Иногда возникают ситуации, когда логика выбора зависит от того, заполнен ли параметр запроса. Посмотрим, как можно реализовать проверку: если задан конкретный лицевой счет, берем его, иначе фильтруем по периоду и улице.

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

Пример использования нескольких условий КОГДА в одном блоке:


ВЫБОР
    КОГДА КУ_ИсковоеЗаявление.СуммаИска <= &СуммаИска И &ВсегдаИск = 1
        ТОГДА КУ_ИсковоеЗаявление.Госпошлина
    ИНАЧЕ 0
КОНЕЦ КАК СуммаГоспошлины

Если результат этого выбора нам нужно использовать для дальнейших сравнений в этом же запросе, помните: в языке запросов 1С нельзя обратиться к псевдониму поля в том же блоке ВЫБРАТЬ. В этом случае мы рекомендуем сначала поместить результат во Временную таблицу, а в следующем запросе пакета уже комфортно работать с вычисленным полем — для этого подойдёт консоль запросов и анализатор СКД для 1С.

Проблема NULL и использование ЕСТЬNULL

Выясним одну из самых коварных причин ошибок — сравнение с NULL. В языке запросов 1С NULL не равен ничему, даже самому себе. Поэтому условие Поле = NULL всегда будет возвращать ложь (или "неизвестно"), и ветка ТОГДА никогда не выполнится.

Проанализируем правильный способ проверки на отсутствие данных при левых соединениях:

  1. Используйте оператор ЕСТЬ NULL вместо знака равенства.
  2. Используйте функцию ЕСТЬNULL() для подстановки значения по умолчанию.

Посмотрим, как упростить громоздкую конструкцию ВЫБОР с помощью ЕСТЬNULL. Вместо такого кода:


ВЫБОР
    КОГДА ВозвратТоваров.Ссылка ЕСТЬ NULL
        ТОГДА Реализация.Сумма
    ИНАЧЕ Реализация.Сумма - ВозвратТоваров.Сумма
КОНЕЦ

Мы можем написать гораздо более лаконичный и производительный вариант:

Реализация.Сумма - ЕСТЬNULL(ВозвратТоваров.Сумма, 0) КАК РеальныйИтог

Этот метод не только короче, но и быстрее работает, так как функция ЕСТЬNULL транслируется в нативные функции SQL-сервера (например, ISNULL), которые оптимизированы на уровне движка базы данных.

Рекомендации по оптимизации

При работе с ВЫБОР КОГДА следует придерживаться нескольких правил для сохранения высокой скорости работы системы:

  1. Порядок условий: Первыми ставьте те условия КОГДА, которые наиболее вероятны. Как только система находит истинное условие, остальные проверки в этом блоке прекращаются.
  2. Индексы: Старайтесь не использовать ВЫБОР в секциях ГДЕ и ПО (условия соединения). Это часто блокирует использование индексов таблиц и приводит к полному сканированию данных.
  3. Типизация: Всегда используйте ВЫРАЗИТЬ при обращении через точку к реквизитам ссылочного типа, если этот тип является составным.
  4. Булевы значения: Помните, что запрос 1С не может вернуть результат логического выражения напрямую. Чтобы получить "Да/Нет" в результате, всегда используйте ВЫБОР КОГДА Условие ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ.

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

← На главную