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

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

Когда, тогда, иначе в 1С: условная логика в запросах и коде

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

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

Главная практическая развилка: если данные нужно отобрать или вычислить прямо в выборке из базы (отчёт, виртуальная таблица, динамический список), используйте ВЫБОР в запросе — это быстрее и не требует обхода результата в коде. Если логика зависит от переменных, пользовательских настроек или требует нескольких действий подряд — используйте ЕСЛИ во встроенном языке.

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

Где применяется каждая конструкция

Платформа 1С содержит два разных «языка» с разным назначением. Язык запросов работает с данными информационной базы: он декларативный, выполняется на уровне СУБД и не умеет выполнять произвольные действия — только выбирать, группировать и вычислять значения. Встроенный язык (похожий на паскалеподобный синтаксис) исполняется в модулях и управляет логикой приложения.

Из этого следуют чёткие зоны ответственности:

  • ВЫБОР КОГДА — в тексте запроса, в схеме компоновки данных (отчёты на СКД), в произвольных выражениях динамических списков и в параметрах виртуальных таблиц.
  • ЕСЛИ ТОГДА — в модулях объектов, форм, общих модулях, обработчиках событий, при программной обработке результата запроса.

Частая ошибка новичков — тянуть всю логику в код: выбрать запросом «сырые» данные, а потом в цикле по выборке рассчитывать признаки через ЕСЛИ. Для больших таблиц это заметно медленнее, чем один ВЫБОР в запросе, потому что каждая итерация цикла — это работа в памяти сервера 1С, а не оптимизированный план СУБД.

Маршрут решения

Как выбрать конструкцию

Нужно вычислить поле в выборке, отчёте или динамическом спискеИспользуйте ВЫБОР КОГДА в тексте запроса или в выражении СКД
Логика зависит от переменных, прав пользователя или требует нескольких операторовИспользуйте ЕСЛИ ТОГДА во встроенном языке
Условие сложное и повторяется в нескольких отчётахВынесите его в вычисляемое поле СКД или в общий модуль с функцией

ВЫБОР КОГДА ТОГДА ИНАЧЕ в запросе: синтаксис и примеры

Полный синтаксис оператора ВЫБОР в языке запросов 1С:

ВЫБОР

КОГДА Продажи.Сумма > 100000

ТОГДА "Крупная"

КОГДА Продажи.Сумма > 10000

ТОГДА "Средняя"

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

КОНЕЦ КАК КатегорияСделки

Условия проверяются сверху вниз, и срабатывает первое истинное. Поэтому порядок веток КОГДА имеет значение: если поставить проверку «больше 10000» выше, чем «больше 100000», крупные сделки никогда не попадут в свою категорию — они будут перехвачены более ранним условием.

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

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

Сокращённая форма и типовые сценарии ВЫБОР

Для простого условия «если — иначе» без цепочки проверок удобнее короткая запись:

ВЫБОР КОГДА Контрагенты.ЮрФизЛицо = ЗНАЧЕНИЕ(Перечисление.ЮрФизЛицо.ЮрЛицо)

ТОГДА "Юридическое лицо"

ИНАЧЕ "Физическое лицо"

КОНЕЦ

Подмена NULL в соединениях

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

ВЫБОР

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

ТОГДА 0

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

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

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

Вычисляемые признаки для отчётов

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

Если одно и то же условие ВЫБОР дублируется в пяти-шести запросах и отчётах, это сигнал вынести признак в данные: например, хранить категорию в дополнительном сведении или вычислять её при записи объекта. Иначе при изменении правила придётся править все запросы вручную.
ПЗ
Практическое замечание

ЕСЛИ ТОГДА ИНАЧЕ во встроенном языке

Условный оператор встроенного языка выполняет не значение, а последовательность действий:

Если Документ.Проведен Тогда

Сообщить("Документ уже проведён");

ИначеЕсли Документ.ПометкаУдаления Тогда

Сообщить("Документ помечен на удаление");

Иначе

Документ.Записать(РежимЗаписиДокумента.Проведение);

КонецЕсли;

Ключевые отличия от ВЫБОР: веток ИначеЕсли может быть сколько угодно, внутри каждой ветки допустимы любые операторы (вызовы процедур, циклы, обращения к базе), а ветка Иначе, как и в запросе, необязательна — но её отсутствие здесь не создаёт NULL, а просто означает «ничего не делать».

Для выбора одного значения из двух существует и функция тернарного типа — в 1С её роль обычно выполняет конструкция через вычисление в выражении или короткий ЕСЛИ в одну строку логики. Длинные цепочки ИначеЕсли (больше четырёх-пяти веток) — признак того, что код лучше переписать через соответствие, таблицу значений с правилами или отдельную функцию.

Типичные ошибки и ограничения

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

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

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

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

Как проверить, что условие работает правильно

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

Порядок проверки
  1. 1
    Выполните запрос в консоли запросов на тестовой копии базы и посмотрите значения вычисляемого поля
  2. 2
    Найдите строки, попадающие в каждую ветку, — включая граничные значения (ровно 10000, ровно 100000)
  3. 3
    Проверьте строки, где исходное поле равно NULL, — они должны попадать в ИНАЧЕ или обрабатываться отдельным КОГДА
  4. 4
    Сравните количество строк по категориям с контрольным запросом с группировкой
  5. 5
    Для кода с ЕСЛИ пройдите ветки отладчиком, расставив точки останова в каждой ветке
Контрольные точки

Как отличить норму от проблемы

Значения вычисляемого поля
Норма

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

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

Встречаются NULL или значения, которых нет ни в одной ветке

Граничные значения
Норма

Значение ровно на границе попадает в задуманную ветку (проверьте > против >=)

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

Граничные строки попадают не туда — перепутаны строгое и нестрогое сравнение

Скорость выполнения
Норма

Запрос с ВЫБОР выполняется сопоставимо с запросом без него

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

Добавление ВЫБОР с разыменованием резко замедлило запрос

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

Альтернативы и смежные приёмы

Не каждая условная задача требует ВЫБОР или ЕСЛИ. В ряде случаев есть более подходящие инструменты:

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

Выбор инструмента по принципу «где живут правила»: если правило — часть бизнес-логики и едино для всех, оно может жить в запросе или коде. Если правило настраивается пользователем или меняется без участия разработчика — оно должно храниться в данных.

Итог

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

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

Частые вопросы

Чем ВЫБОР в запросе отличается от ЕСЛИ в коде?

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

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

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

Почему сравнение с NULL через «=» не работает?

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

Как в запросе посчитать сумму только по строкам, удовлетворяющим условию?

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

Что быстрее: ВЫБОР в запросе или ЕСЛИ в цикле по выборке?

На больших объёмах данных ВЫБОР в запросе заметно быстрее: СУБД вычисляет поле в рамках одного плана выполнения. Обход выборки в цикле с ЕСЛИ требует передачи всех данных в память сервера 1С и построчной обработки. Цикл оправдан только когда внутри условия нужны действия, невозможные в запросе.

Можно ли вкладывать ВЫБОР внутрь ВЫБОР?

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