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