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

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

ИНАЧЕ и КОГДА в запросе 1С 8.3: как работает конструкция ВЫБОР

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

В языке запросов 1С 8.3 нет привычного оператора «если — иначе» из встроенного языка. Вместо него используется конструкция ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ. Именно ветка ИНАЧЕ отвечает за значение «по умолчанию», которое вернёт запрос, если ни одно из условий КОГДА не выполнилось. Понимание того, как она работает, критично: без неё запрос вернёт NULL, а это частая причина «пропавших» сумм в отчётах и странных итогов в СКД.

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

Типичные задачи, где без ИНАЧЕ не обойтись: подстановка нуля вместо NULL в остатках, расчёт скидки по диапазонам сумм, текстовое представление статуса документа (число → строка), выбор курса валюты с запасным вариантом, замена пустых ссылок осмысленным значением. Ниже разобран синтаксис, рабочие примеры и ошибки, которые допускают даже опытные разработчики.

Синтаксис конструкции ВЫБОР КОГДА ТОГДА ИНАЧЕ КОНЕЦ

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

ВЫБОР

КОГДА Условие1

ТОГДА Значение1

КОГДА Условие2

ТОГДА Значение2

ИНАЧЕ ЗначениеПоУмолчанию

КОНЕЦ

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

Существует и упрощённая форма без условий — сравнение выражения со списком значений:

ВЫБОР Документ.ВидОперации

КОГДА ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа)

ТОГДА "Реализация"

ИНАЧЕ "Прочее"

КОНЕЦ

Обе формы взаимозаменяемы, но первая гибче: в условиях можно использовать любые логические выражения, включая сравнения, МЕЖДУ, В и проверки на NULL.

Простой пример: статус документа текстом

Классическая задача — вывести в отчёте человекочитаемый статус вместо служебного признака. Допустим, нужно показать, проведён документ или нет:

ВЫБРАТЬ

Док.Ссылка КАК Документ,

ВЫБОР

КОГДА Док.Проведен

ТОГДА "Проведён"

КОГДА Док.ПометкаУдаления

ТОГДА "Помечен на удаление"

ИНАЧЕ "Черновик"

КОНЕЦ КАК Статус

ИЗ

Документ.РеализацияТоваровУслуг КАК Док

Здесь ветка ИНАЧЕ ловит все документы, которые не проведены и не помечены — это и есть «черновики». Обратите внимание на порядок условий: помеченный на удаление проведённый документ формально попадает под оба условия, но сработает первое — «Проведён». Если бизнес-логика требует показывать пометку в приоритете, поменяйте условия местами.

Результат проверяется просто: выполните запрос в консоли запросов и убедитесь, что в колонке «Статус» нет пустых значений и NULL. Если пустые строки есть — значит, ветка ИНАЧЕ отсутствует или типы значений в ветках несовместимы.

ИНАЧЕ и NULL: подстановка значений по умолчанию

Самое частое применение ИНАЧЕ — борьба с NULL после левого соединения. Когда вы присоединяете таблицу остатков к справочнику номенклатуры, для позиций без движений поля остатков будут NULL. Суммировать NULL напрямую нельзя: NULL + 5 = NULL.

ВЫБРАТЬ

Товары.Ссылка КАК Номенклатура,

ВЫБОР

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

ТОГДА 0

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

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

ИЗ

Справочник.Номенклатура КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Товары.Ссылка = Остатки.Номенклатура

Для этой же задачи есть короткая альтернатива — функция ЕСТЬNULL(Остатки.КоличествоОстаток, 0). Она компактнее и читается легче. ВЫБОР с ИНАЧЕ оправдан, когда логика сложнее простой замены NULL: например, отрицательный остаток нужно показать как 0, а NULL — как «нет данных».

ЕСТЬNULL или ВЫБОР с ИНАЧЕ

ЕСТЬNULL(Поле, 0)

Подходит для простой замены NULL одним значением. Короче и быстрее читается. Не умеет ничего, кроме подстановки.

ВЫБОР КОГДА ... ИНАЧЕ

Нужен, когда условий несколько или значение зависит от логики: диапазоны, несколько полей, разные типы замены. Избыточен для простой замены NULL.

Несколько условий: диапазоны и градации

Ветка ИНАЧЕ в многоступенчатых условиях обычно означает «всё остальное» — верхний или нижний диапазон, который не нужно проверять явно. Пример — категория клиента по сумме закупок:

ВЫБОР

КОГДА Продажи.СуммаОборот >= 1000000

ТОГДА "VIP"

КОГДА Продажи.СуммаОборот >= 300000

ТОГДА "Крупный"

КОГДА Продажи.СуммаОборот >= 50000

ТОГДА "Средний"

ИНАЧЕ "Малый"

КОНЕЦ КАК КатегорияКлиента

Здесь важно, что условия проверяются сверху вниз. Если клиент потратил 1 200 000, он попадёт в первую ветку, и остальные проверяться не будут. Поэтому диапазоны записывают от большего к меньшему — либо используют двусторонние условия с МЕЖДУ, если порядок не гарантирован.

Ещё одна тонкость: если СуммаОборот равна NULL (клиента нет в оборотах), ни одно сравнение не выполнится — сравнение с NULL всегда даёт «неизвестно», а не истину. В этом случае сработает именно ИНАЧЕ, и клиент получит категорию «Малый». Если это нежелательно, добавьте первым условием явную проверку КОГДА Продажи.СуммаОборот ЕСТЬ NULL ТОГДА "Нет продаж".

ИНАЧЕ в агрегатных функциях и итогах

Мощный приём — использовать ВЫБОР внутри СУММА() для расчёта нескольких показателей одним проходом по таблице. Например, разложить обороты по признаку оплаты:

ВЫБРАТЬ

Расчёты.Контрагент,

СУММА(ВЫБОР

КОГДА Расчёты.Оплачено

ТОГДА Расчёты.Сумма

ИНАЧЕ 0

КОНЕЦ) КАК Оплачено,

СУММА(ВЫБОР

КОГДА Расчёты.Оплачено

ТОГДА 0

ИНАЧЕ Расчёты.Сумма

КОНЕЦ) КАК Долг

ИЗ

РегистрНакопления.РасчётыСКонтрагентами.Обороты КАК Расчёты

СГРУППИРОВАТЬ ПО

Расчёты.Контрагент

Здесь ИНАЧЕ 0 обязателен: без него в агрегат попадёт NULL, и хотя СУММА игнорирует NULL при вычислении, результат для группы, где все значения NULL, тоже будет NULL. С нулём вы гарантированно получите число, которое можно сравнивать и выводить.

Тот же приём работает в СКД при настройке вычисляемых полей и ресурсов: выражение ресурса СУММА(ВЫБОР КОГДА ... ИНАЧЕ 0 КОНЕЦ) позволяет строить кросс-отчёты без дополнительных наборов данных.

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

Типичные ошибки при использовании ИНАЧЕ

Первая и самая распространённая — пропущенная ветка ИНАЧЕ. Запрос выполнится без ошибки, но для всех строк, не попавших ни в одно условие, вернётся NULL. В отчёте это выглядит как пустые ячейки, а при дальнейших вычислениях — как «исчезнувшие» суммы.

Вторая ошибка — несовместимые типы в ветках. Например, ТОГДА 0 и ИНАЧЕ "нет данных". Консоль запросов может проглотить такое, но при группировке, сортировке или выводе в СКД начнутся сюрпризы. Правило: все ветки возвращают один тип.

Третья — неправильный порядок условий при пересекающихся диапазонах. Если первым стоит КОГДА Сумма > 100, то условие КОГДА Сумма > 1000 ниже него не сработает никогда. Частное условие всегда выше общего.

Четвёртая — ожидание, что ИНАЧЕ отловит NULL в проверяемом поле. Отловит, но только потому, что все сравнения с NULL ложны. Если NULL нужно обработать осмысленно (а не свалить в «всё остальное»), добавляйте явную ветку ЕСТЬ NULL.

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

Производительность и ограничения

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

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

В запросах к большим таблицам также избегайте десятков веток КОГДА с вычисляемыми выражениями — каждое условие проверяется для каждой строки. Если градаций много (например, справочник категорий), надёжнее хранить соответствие в регистре сведений и соединяться с ним.

Как проверить, что ИНАЧЕ работает правильно

Базовая проверка — выполнить запрос в консоли запросов на реальных данных и отсортировать результат по вычисляемой колонке. Значения «по умолчанию» должны появиться именно у тех строк, где не сработало ни одно условие. Если таких строк нет вообще — либо условия покрывают все случаи, либо данные теста неполные.

Полезно искусственно создать граничные случаи: строку с NULL в ключевом поле, значение ровно на границе диапазона, значение за пределами всех диапазонов. Для каждого случая результат должен быть предсказуемым. Особое внимание — границам: условие >= 1000000 и > 1000000 дадут разный результат для суммы ровно в миллион.

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

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

Колонка с ВЫБОР в результате запроса
Норма

Нет пустых значений и NULL, все строки получили осмысленное значение

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

Есть NULL — ветка ИНАЧЕ отсутствует или не покрывает случаи

Строка с NULL в исходном поле
Норма

Попадает в явную ветку ЕСТЬ NULL или осмысленно в ИНАЧЕ

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

Попадает в ИНАЧЕ случайно, смешиваясь с реальными 'прочими'

Значение на границе диапазона
Норма

Попадает в ожидаемую категорию согласно >= или >

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

Граничное значение отнесено не туда из-за неверного знака сравнения

FAQ

Что вернёт запрос, если не указать ИНАЧЕ и ни одно условие не выполнилось?

Запрос вернёт NULL для такой строки. Ошибки не будет — синтаксически ветка ИНАЧЕ необязательна. Но NULL в результате ломает арифметику, сравнения и отображение в отчётах, поэтому ИНАЧЕ рекомендуется писать всегда, даже если это ИНАЧЕ 0 или ИНАЧЕ "".

Чем ИНАЧЕ в запросе отличается от Иначе во встроенном языке 1С?

Это разные языки. Во встроенном языке «Если...Иначе...КонецЕсли» управляет выполнением кода. В запросе ВЫБОР...ИНАЧЕ...КОНЕЦ — выражение, вычисляемое для каждой строки результата. Написать «Если» внутри запроса нельзя — это синтаксическая ошибка.

Можно ли использовать несколько ИНАЧЕ в одной конструкции ВЫБОР?

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

Что лучше для замены NULL: ЕСТЬNULL или ВЫБОР с ИНАЧЕ?

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

Работает ли ВЫБОР КОГДА ИНАЧЕ в СКД и динамических списках?

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

Почему условие КОГДА Поле = NULL не срабатывает?

Потому что NULL не равен ничему, включая сам себя: любое сравнение с NULL даёт неопределённый результат, который трактуется как ложь. Проверка пишется только так: КОГДА Поле ЕСТЬ NULL ТОГДА ... — это единственный корректный способ в языке запросов 1С.

Итог

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

ИНАЧЕ — ветка по умолчанию конструкции ВЫБОР КОГДА ТОГДА ИНАЧЕ КОНЕЦ. Указывайте её всегда: без неё запрос возвращает NULL. Следите за порядком условий (частные — выше общих), совместимостью типов во всех ветках и явной обработкой NULL через ЕСТЬ NULL. Для простой замены NULL используйте ЕСТЬNULL, для фильтрации данных — секцию ГДЕ, а ВЫБОР оставьте для преобразования значений.