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

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

Как проверить тип значения в запросе 1С

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

В запросах 1С часто встречаются поля составного типа: например, реквизит «Контрагент» может хранить ссылку на справочник «Контрагенты» или «ФизическиеЛица», а поле «ДокументОснование» — ссылку на несколько видов документов. Чтобы корректно отфильтровать, сгруппировать или соединить такие данные, нужно уметь определять фактический тип значения прямо в тексте запроса.

Язык запросов 1С предоставляет для этого три основных инструмента: функцию ТИПЗНАЧЕНИЯ(), которая возвращает тип конкретного значения, функцию ТИП(), задающую тип-константу для сравнения, и оператор ССЫЛКА, проверяющий принадлежность ссылки к конкретной таблице. Каждый из них имеет свои ограничения и сценарии применения.

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

Функция ТИПЗНАЧЕНИЯ: базовый способ проверки типа

Функция ТИПЗНАЧЕНИЯ(<Выражение>) возвращает тип переданного значения. Сам по себе результат нельзя вывести как строку — его сравнивают с конкретным типом, заданным функцией ТИП(). Конструкция выглядит так:

ВЫБРАТЬ

Расчеты.Регистратор КАК Регистратор

ИЗ

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

ГДЕ

ТИПЗНАЧЕНИЯ(Расчеты.Регистратор) = ТИП(Документ.РеализацияТоваровУслуг)

Такой запрос вернёт только те записи регистра, регистратором которых является документ «РеализацияТоваровУслуг», даже если регистратором может выступать десяток разных видов документов. Это типичная задача при анализе движений регистров.

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

Функция ТИП: задание типа для сравнения

Функция ТИП(<ИмяТипа>) используется только в паре с ТИПЗНАЧЕНИЯ и задаёт конкретный тип данных. Аргумент указывается без кавычек, как имя объекта метаданных: ТИП(Справочник.Контрагенты), ТИП(Документ.ПоступлениеТоваровУслуг), ТИП(Перечисление.СтавкиНДС).

Для примитивных типов синтаксис отличается: ТИП(ЧИСЛО), ТИП(СТРОКА), ТИП(ДАТА), ТИП(БУЛЕВО). Это позволяет проверять, например, реквизиты универсальных регистров сведений, где одно поле может хранить и строку, и число.

Частая ошибка — попытка сравнить ТИПЗНАЧЕНИЯ(Поле) со строкой, например = "СправочникСсылка.Контрагенты". Такой запрос либо не выполнится, либо вернёт пустой результат: тип значения — это не строка. Сравнивать нужно только с результатом функции ТИП().

Оператор ССЫЛКА: проверка ссылочных типов

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

ВЫБРАТЬ

Заказы.ДокументОснование КАК Основание

ИЗ

Документ.ЗаказПокупателя КАК Заказы

ГДЕ

Заказы.ДокументОснование ССЫЛКА Документ.СчетНаОплатуПокупателю

Оператор применим только к ссылкам: проверить им примитивный тип (число, строку) нельзя. Если поле может содержать и ссылки, и примитивы, комбинируйте ССЫЛКА с ТИПЗНАЧЕНИЯ через логическое ИЛИ.

По производительности ССЫЛКА и ТИПЗНАЧЕНИЯ в большинстве случаев эквивалентны, но ССЫЛКА короче записывается и проще читается, поэтому для ссылок его принято использовать в первую очередь.

Способы проверки типа

ТИПЗНАЧЕНИЯ + ТИП

Универсальный вариант: работает со ссылками и примитивными типами. Запись длиннее, легко ошибиться в имени типа.

Оператор ССЫЛКА

Только для ссылочных значений. Короткая и наглядная запись, но не проверяет числа, строки и даты.

ВЫРАЗИТЬ(Поле КАК Тип)

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

Конструкция ВЫБОР КОГДА: разветвление логики по типу

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

ВЫБРАТЬ

ВЫБОР

КОГДА Расчеты.Контрагент ССЫЛКА Справочник.Контрагенты

ТОГДА ВЫРАЗИТЬ(Расчеты.Контрагент КАК Справочник.Контрагенты).Наименование

КОГДА Расчеты.Контрагент ССЫЛКА Справочник.ФизическиеЛица

ТОГДА ВЫРАЗИТЬ(Расчеты.Контрагент КАК Справочник.ФизическиеЛица).ФИО

ИНАЧЕ "Не задан"

КОНЕЦ КАК ПредставлениеКонтрагента

ИЗ

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

Обратите внимание на приём с ВЫРАЗИТЬ: обратиться к реквизиту ссылки через точку (Поле.Наименование) для составного типа можно, но платформа построит соединения со всеми возможными таблицами, что замедляет запрос. Предварительное приведение через ВЫРАЗИТЬ ограничивает соединение одной таблицей и ускоряет выполнение.

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

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

ВЫРАЗИТЬ: приведение составного типа и его роль в проверках

Функция ВЫРАЗИТЬ(<Поле> КАК <Тип>) формально не проверяет тип, а приводит значение к заданному. Если фактический тип не совпадает, результатом будет NULL. На этом поведении построен приём «проверки через приведение»: значение после ВЫРАЗИТЬ не равно NULL только тогда, когда тип совпал.

ВЫБРАТЬ

ВЫРАЗИТЬ(Регистратор КАК Документ.РеализацияТоваровУслуг) КАК Реализация

ИЗ

РегистрНакопления.Продажи КАК Продажи

ГДЕ

НЕ ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг) ЕСТЬ NULL

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

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

Ограничения и особенности платформы

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

В-третьих, в запросах к внешним источникам данных и в некоторых сценариях СКД поведение ТИПЗНАЧЕНИЯ может отличаться — там проверку типа часто выносят в вычисляемые поля на встроенном языке. В-четвёртых, индексация по условию с ТИПЗНАЧЕНИЯ не работает: на больших таблицах фильтр по типу регистратора выполняется полным перебором, поэтому его стоит сочетать с другими отборами, сужающими выборку.

Типичные ошибки при проверке типа

Первая и самая распространённая ошибка — сравнение ТИПЗНАЧЕНИЯ со строковым литералом вместо функции ТИП(). Вторая — забытая обработка NULL: составное поле может быть не заполнено, и тогда все проверки типа дадут ЛОЖЬ, а строка «выпадет» из результата без предупреждения.

Третья ошибка — обращение через точку к реквизитам составного поля без ВЫРАЗИТЬ. Запрос выполнится, но соединится со всеми таблицами составного типа, что на больших данных кратно увеличивает время выполнения. Четвёртая — попытка использовать ССЫЛКА для примитивных типов: оператор выдаст ошибку исполнения.

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

Проверка результата и отладка

Надёжный способ убедиться, что проверка типа работает, — выполнить запрос в консоли запросов и вывести само поле рядом с результатом проверки. Если условие с ТИПЗНАЧЕНИЯ не срабатывает ни для одной строки, первым делом проверьте, правильно ли указано имя объекта метаданных в ТИП(): оно должно точно совпадать с именем в конфигураторе.

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

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

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

Запрос выполняется без ошибок
Норма

Все имена типов в ТИП() совпадают с метаданными, ССЫЛКА применена только к ссылкам

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

Ошибка исполнения — неверное имя типа или ССЫЛКА на примитивном поле

Количество строк в выборке
Норма

Совпадает с ожидаемым количеством записей нужного типа

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

Строк меньше — вероятно, потеряны NULL или не учтён какой-то тип

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

Запрос отрабатывает за приемлемое время

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

Долгое выполнение — нет сужающих отборов, фильтр по типу идёт полным перебором

FAQ

Можно ли проверить тип значения NULL в запросе?

Нет. У значения NULL нет типа, поэтому ТИПЗНАЧЕНИЯ(Поле) для NULL возвращает NULL, а любое сравнение с ТИП() даёт ЛОЖЬ. Проверяйте такие значения отдельно условием Поле ЕСТЬ NULL.

Чем отличается ТИПЗНАЧЕНИЯ от ВЫРАЗИТЬ?

ТИПЗНАЧЕНИЯ только сообщает тип и используется в условиях. ВЫРАЗИТЬ преобразует значение к указанному типу: при совпадении возвращает само значение, при несовпадении — NULL. ВЫРАЗИТЬ нужен, когда дальше требуется обращение к реквизитам ссылки.

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

Используйте сравнение ТИПЗНАЧЕНИЯ(Поле) = ТИП(ЧИСЛО). Оператор ССЫЛКА здесь не подходит — он работает только со ссылочными значениями.

Можно ли использовать ТИПЗНАЧЕНИЯ в параметрах виртуальных таблиц?

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

Почему условие ССЫЛКА не находит записи, хотя документы такого вида есть?

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

Итог

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

Для проверки типа в запросе 1С используйте ТИПЗНАЧЕНИЯ в паре с ТИП() или оператор ССЫЛКА для ссылок. Обращение к реквизитам составной ссылки делайте через ВЫРАЗИТЬ. Всегда обрабатывайте NULL и ветку ИНАЧЕ, а на больших таблицах сочетайте фильтр по типу с другими отборами.