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