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