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

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

Как проверить тип ссылки в 1С

Способы проверить тип ссылки в 1С: функция ТипЗнч, оператор Тип, метаданные и запросы. Примеры кода для встроенного языка и языка запросов 1С.

Проверка типа ссылки — одна из самых частых задач при разработке и доработке конфигураций 1С. Она возникает, когда реквизит объекта имеет составной тип (например, контрагент может быть физическим или юридическим лицом), когда процедура получает параметр произвольного типа или когда нужно отфильтровать данные в запросе по конкретному виду документа.

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

Ошибка в определении типа приводит к обращениям к несуществующим реквизитам, падению кода с исключением или некорректным данным в отчётах. Поэтому важно не только знать синтаксис, но и понимать, какой метод выбрать в конкретной ситуации и как проверить результат.

Что такое ссылка и зачем проверять её тип

Ссылка в 1С — это значение, которое однозначно идентифицирует объект базы данных: элемент справочника, документ, план счетов и т.д. Ссылка содержит уникальный идентификатор объекта и информацию о типе, но не хранит данные самого объекта — реквизиты подтягиваются из базы при обращении через точку.

Проверка типа нужна в нескольких типовых ситуациях. Во-первых, при работе с составными типами: если реквизит «Плательщик» может хранить ссылку и на справочник «Контрагенты», и на «ФизическиеЛица», перед обращением к специфичным реквизитам нужно понять, что именно лежит в поле. Во-вторых, при универсальных обработках, где процедура принимает «произвольную ссылку». В-третьих, при отладке, когда нужно быстро выяснить, какой объект пришёл в параметр.

Проверка типа через ТипЗнч() и Тип() во встроенном языке

Основной способ — функция ТипЗнч(Значение), которая возвращает тип переданного значения. Результат сравнивают с типом, полученным через функцию Тип(ИмяТипа), где имя указывается строкой по шаблону «ВидОбъекта.ИмяОбъекта»:

Если ТипЗнч(Плательщик) = Тип("СправочникСсылка.Контрагенты") Тогда

Сообщить("Это контрагент: " + Плательщик.ИНН);

ИначеЕсли ТипЗнч(Плательщик) = Тип("СправочникСсылка.ФизическиеЛица") Тогда

Сообщить("Это физическое лицо");

КонецЕсли;

Имя типа для документов строится как ДокументСсылка.РеализацияТоваровУслуг, для планов счетов — ПланСчетовСсылка.Хозрасчетный и так далее. Ошибка в имени (несуществующий объект, опечатка) вызовет исключение уже на этапе выполнения функции Тип(), поэтому имя лучше копировать из конфигуратора, а не набирать вручную.

bsl
Если ТипЗнч(ДокОснование) = Тип("ДокументСсылка.ЗаказКлиента") Тогда
    // логика для заказа
ИначеЕсли ТипЗнч(ДокОснование) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
    // логика для счёта
КонецЕсли;

Определение вида объекта через Метаданные()

Когда нужно не сравнить тип с конкретным значением, а узнать, что за объект пришёл, удобнее метод Метаданные(). Он доступен у любой ссылки и возвращает объект описания конфигурации, у которого есть свойства Имя, Синоним, ПолноеИмя():

МетаданныеСсылки = Ссылка.Метаданные();

Сообщить(МетаданныеСсылки.Имя); // "Контрагенты"

Сообщить(МетаданныеСсылки.ПолноеИмя()); // "Справочник.Контрагенты"

Через родителя метаданных можно определить общий вид объекта, не перечисляя все типы: например, проверить, что ссылка — это вообще документ, а не справочник. Для этого используют функции вида Метаданные.Документы.Содержит(Ссылка.Метаданные()) или сравнение строки полного имени.

Проверка типа ссылки в запросе

В языке запросов сравнение через ТипЗнч() недоступно — там используются собственные конструкции. Самый производительный способ отфильтровать записи по типу — оператор ССЫЛКА:

ВЫБРАТЬ

Расчеты.Плательщик

ИЗ

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

ГДЕ

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

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

ССЫЛКА или ТИПЗНАЧЕНИЯ в запросе

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

Предпочтителен в условии ГДЕ: лучше оптимизируется СУБД, короче записывается. Ограничение — нельзя использовать в списке выбираемых полей для вывода признака.

Функция ТИПЗНАЧЕНИЯ()

Подходит, когда тип нужно вывести в результат запроса или использовать в ВЫБОР ... КОГДА. Может работать медленнее на больших таблицах при фильтрации.

Как выбрать способ проверки в разных сценариях

Выбор метода зависит от контекста: модуль объекта, произвольный код, запрос или отладка. Ниже — маршрут выбора для типовых ситуаций.

Маршрут решения

Какой способ выбрать

Нужно сравнить значение с одним-двумя конкретными типами в кодеИспользуйте ТипЗнч(Значение) = Тип("Вид.Имя") — самый читаемый и быстрый вариант
Нужно узнать имя или вид произвольной ссылкиИспользуйте Ссылка.Метаданные().Имя или ПолноеИмя()
Нужно отфильтровать записи в запросеИспользуйте оператор ССЫЛКА в секции ГДЕ
Нужно ветвление по типу прямо в тексте запроса с выводом разных полейИспользуйте ВЫБОР КОГДА Поле ССЫЛКА Справочник.А ТОГДА ... ИНАЧЕ ... КОНЕЦ
Нужно проверить, является ли значение вообще ссылкойИспользуйте Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) или аналог для документов

Для отладки в толстом или тонком клиенте проще всего вычислить выражение ТипЗнч(Переменная) в табло — платформа покажет строковое представление типа. Также в конфигураторе можно посмотреть составной тип реквизита прямо в палитре свойств объекта: там перечислены все допустимые виды ссылок.

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

Первая распространённая ошибка — сравнение типа со строкой: конструкция ТипЗнч(Ссылка) = "СправочникСсылка.Контрагенты" всегда вернёт Ложь, потому что слева объект типа «Тип», а справа строка. Сравнивать нужно только с результатом функции Тип().

Вторая ошибка — обращение к реквизиту до проверки типа. Если в поле может лежать ссылка на разные справочники, код Плательщик.ИНН упадёт с ошибкой «Поле объекта не обнаружено» для тех видов объектов, где такого реквизита нет. Сначала проверка типа, потом обращение к специфичным данным.

Третья ошибка — игнорирование пустой ссылки и Неопределено. У составного реквизита значение может быть не заполнено, и ТипЗнч() вернёт тип «Неопределено» или тип пустой ссылки конкретного вида. Проверку на ЗначениеЗаполнено() стоит выполнять до анализа типа, если пустые значения не нужны.

Типичные ошибки
01
Сравнение ТипЗнч() со строкой вместо Тип() — условие никогда не выполняется, ветка кода молча пропускается
02
Обращение к реквизиту ссылки до проверки типа — исключение «Поле объекта не обнаружено» на объектах другого вида
03
Опечатка в имени типа внутри Тип("...") — исключение в момент выполнения, которое сложно найти в редко выполняемой ветке
04
Фильтрация по типу в запросе через соединение вместо оператора ССЫЛКА — лишние соединения и замедление запроса
05
Забытая обработка Неопределено и пустой ссылки — непредсказуемое поведение на незаполненных реквизитах

Как проверить результат и убедиться в корректности

После внедрения проверки типа протестируйте код на всех видах объектов, которые реально встречаются в данных. Для составного реквизита создайте или найдите тестовые записи с каждым допустимым типом и прогоните через них обработку. Особое внимание — записям с незаполненным значением.

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

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

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

Ветка кода по типу
Норма

Для каждого вида ссылки выполняется своя ветка, обращений к несуществующим реквизитам нет

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

На части данных возникает «Поле объекта не обнаружено» или выполняется не та ветка

Фильтр по типу в запросе
Норма

В результат попадают только записи нужного вида, количество строк соответствует ожиданию

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

Записи нужного типа отсутствуют или попадают лишние — проверьте имя объекта и условие

Пустые значения
Норма

Незаполненные реквизиты обработаны отдельной веткой или отфильтрованы

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

Код падает или ведёт себя непредсказуемо на пустых ссылках

FAQ: частые вопросы о проверке типа ссылки

Чем ТипЗнч() отличается от Тип()?

ТипЗнч(Значение) возвращает тип конкретного значения, переданного в параметре. Тип("СтрокаИмени") создаёт объект типа по его строковому имени. Обычно они используются в паре: результат первой сравнивают с результатом второй.

Как проверить, что значение вообще является ссылкой, а не числом или строкой?

Используйте конструкцию вида Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) — она вернёт Истина для любой ссылки на справочник. Аналогичные методы есть у Документы, ПланыСчетов и других менеджеров. Для объединения проверяйте несколько менеджеров через ИЛИ.

Можно ли проверить тип ссылки в СКД?

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

Как узнать тип ссылки, если у меня есть только её строковое представление или GUID?

По уникальному идентификатору тип определяется перебором: нужно знать предполагаемый вид объекта и получить ссылку через Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)), затем проверить существование через НайтиПоСсылке или проверку на пустую ссылку. Универсального способа определить тип по одному GUID без перебора видов объектов в платформе нет.

Что быстрее: ТипЗнч() или Метаданные()?

Сравнение через ТипЗнч() и Тип() работает быстрее и не требует обращения к метаданным. Метод Метаданные() оправдан, когда нужно имя объекта или универсальная обработка произвольных ссылок, а не просто сравнение с известным типом.

Почему условие с ТипЗнч() не срабатывает, хотя тип вроде правильный?

Чаще всего причина в том, что значение — это не ссылка, а объект (например, СправочникОбъект вместо СправочникСсылка), либо в значении лежит Неопределено. Выведите ТипЗнч(Значение) через Сообщить или смотрите в табло отладчика — там будет точное имя фактического типа.

Итог

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

Во встроенном языке тип ссылки проверяют через ТипЗнч() в паре с Тип(), имя и вид объекта узнают через Метаданные(), а в запросах используют оператор ССЫЛКА. Перед обращением к реквизитам составного поля всегда проверяйте тип и обрабатывайте пустые значения — это защищает код от исключений.