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