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