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

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

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

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

Проверка типа значения в запросе 1С — типовая задача при работе с составными полями: реквизитами, которые могут хранить ссылки на разные справочники, с документами-основаниями разных видов, с полями типа «Характеристика» и произвольными данными в регистрах сведений. Без явной проверки типа запрос либо возвращает неожиданные NULL, либо падает с ошибкой при попытке обратиться «через точку» к реквизиту, которого нет у части ссылок.

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

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

Какие инструменты проверки типа есть в языке запросов

Язык запросов 1С не имеет булевой функции «ЭтоТип» в привычном виде, но предлагает четыре рабочих механизма, которые покрывают все сценарии проверки типа. Их часто путают, поэтому важно понимать различия до написания запроса.

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

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

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

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

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

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

ВЫРАЗИТЬ

Не проверяет тип, а приводит его; используется для доступа к реквизитам составного поля и сужения типа в СКД. Неподходящие значения превращаются в NULL.

ВЫБОР КОГДА

Позволяет комбинировать проверки и возвращать разные значения для разных типов. Ограничение: громоздкий синтаксис при большом числе вариантов.

Проверка типа через ТИПЗНАЧЕНИЯ и ТИП()

Функция ТИПЗНАЧЕНИЯ() возвращает тип значения указанного поля, а конструктор ТИП() формирует значение типа «Тип» для сравнения. Связка используется в условиях ГДЕ и в конструкциях ВЫБОР.

ВЫБРАТЬ

Заказ.Основание КАК Основание

ИЗ

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

ГДЕ

ТИПЗНАЧЕНИЯ(Заказ.Основание) = ТИП(Документ.СчетНаОплату)

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

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

bsl
ВЫБРАТЬ
	ТИПЗНАЧЕНИЯ(Поле) КАК ТипПоля,
	КОЛИЧЕСТВО(*) КАК Количество
ИЗ
	РегистрСведений.ЗначенияСвойств КАК Значения
СГРУППИРОВАТЬ ПО
	ТИПЗНАЧЕНИЯ(Поле)

Проверка принадлежности к виду объекта через ССЫЛКА

Оператор ССЫЛКА — самый лаконичный способ проверить, что значение является ссылкой на объект конкретного вида. Синтаксис: Поле ССЫЛКА Справочник.Контрагенты. Результат — булево, поэтому выражение можно использовать напрямую в ГДЕ без знака равенства.

ВЫБРАТЬ

Оплата.Плательщик КАК Плательщик

ИЗ

Документ.ПоступлениеНаСчет КАК Оплата

ГДЕ

Оплата.Плательщик ССЫЛКА Справочник.Контрагенты

Если составное поле может содержать несколько допустимых видов ссылок, условия объединяются через ИЛИ:

ГДЕ

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

ИЛИ Док.Основание ССЫЛКА Документ.СчетНаОплату)

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

Безопасный доступ к реквизитам составного поля через ВЫРАЗИТЬ

Главная практическая проблема составных полей — обращение «через точку». Если реквизит «Контрагент» может хранить ссылку на справочник «Контрагенты» или «Организации», то обращение Док.Контрагент.ИНН вернёт NULL для всех строк, где тип не совпадает, а в ряде случаев запрос не сможет построить план и выдаст ошибку.

Конструкция ВЫРАЗИТЬ решает это: она приводит значение к указанному типу, а значения других типов заменяет на NULL. После приведения платформа «знает» тип поля и позволяет обращаться к его реквизитам:

ВЫБРАТЬ

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

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

ИЗ

Документ.СчетФактура КАК Док

Побочный эффект ВЫРАЗИТЬ — сужение типа поля в результате запроса. Это полезно в СКД и динамических списках: поле, приведённое к единственному типу, корректно отображается, сортируется и участвует в отборах без дополнительных настроек.

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

Проверка типа в ВЫБОР КОГДА и в параметрах виртуальных таблиц

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

ВЫБРАТЬ

ВЫБОР

КОГДА Свойство.Значение ССЫЛКА Справочник.Номенклатура

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

КОГДА ТИПЗНАЧЕНИЯ(Свойство.Значение) = ТИП(СТРОКА)

ТОГДА Свойство.Значение

КОГДА ТИПЗНАЧЕНИЯ(Свойство.Значение) = ТИП(ЧИСЛО)

ТОГДА Свойство.Значение

ИНАЧЕ NULL

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

ИЗ

РегистрСведений.ДополнительныеСведения КАК Свойство

Проверка типа допустима и в параметрах виртуальных таблиц регистров. Например, при обращении к таблице остатков с отбором по составному измерению условие Склад ССЫЛКА Справочник.Склады можно передать прямо в параметры виртуальной таблицы — это сократит объём выбираемых данных до соединения.

При этом помните про ограничение: в параметрах виртуальных таблиц допустимы не все выражения языка запросов. Если конструктор запроса отказывается принимать условие, вынесите проверку типа в секцию ГДЕ основного запроса.

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

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

Вторая ошибка — обращение к реквизиту составного поля без ВЫРАЗИТЬ и последующее удивление «пустым» результатом. NULL от несовпадающего типа не вызывает ошибку, поэтому проблема обнаруживается поздно, обычно на этапе проверки отчёта.

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

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

Как проверить результат и выбрать подходящий способ

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

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

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

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

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

Результат возвращается, строки с разными типами присутствуют

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

Ошибка «Поле не найдено» или пустой результат

Строки с «чужим» типом
Норма

В вычисляемых полях стоит NULL, строка не исчезает (если отбор не задан)

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

Строки пропадают без условия ГДЕ

Поле после ВЫРАЗИТЬ в СКД
Норма

Отборы и сортировка работают, тип поля единственный

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

Поле недоступно для отбора или отображается пустым

Покрытие типов
Норма

Группировка по ТИПЗНАЧЕНИЯ показывает только ожидаемые типы

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

В данных обнаружены неучтённые типы, дающие NULL

Частые вопросы о проверке типа в запросе 1С

Чем отличается ТИПЗНАЧЕНИЯ от оператора ССЫЛКА?

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

Можно ли проверить тип значения в условии соединения таблиц?

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

Почему ВЫРАЗИТЬ возвращает NULL для всех строк?

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

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

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

Работает ли проверка типа в СКД и динамических списках?

Да, все перечисленные конструкции поддерживаются в тексте запроса для СКД и динамических списков. Дополнительно в СКД рекомендуется сужать составное поле через ВЫРАЗИТЬ, чтобы поле корректно участвовало в отборах, группировках и выводе.

Можно ли сравнить типы двух полей между собой?

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

Итог

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

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