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

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

1С: как определить тип метаданных объекта

Как определить тип метаданных в 1С через конфигуратор, запросы и встроенный язык: ТипЗнч, Метаданные(), НайтиПоТипу. Примеры кода и типичные ошибки.

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

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

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

Что такое тип метаданных и зачем его определять

Метаданные в 1С — это описание структуры прикладного решения: какие существуют справочники, документы, регистры, перечисления, планы счетов и другие объекты. Каждый объект конфигурации принадлежит к определённому виду (классу) метаданных — например, «Справочник», «Документ», «РегистрНакопления».

Знание типа метаданных критично в универсальных алгоритмах. Например, обработка удаления помеченных объектов должна по-разному работать со справочниками и документами, а механизм обмена — понимать, какие реквизиты доступны у объекта данного вида.

Определение типа в конфигураторе

Самый простой способ — визуальный. Откройте конфигуратор и дерево конфигурации (меню «Конфигурация» → «Открыть конфигурацию»). Объекты сгруппированы по веткам: «Справочники», «Документы», «Регистры сведений» и так далее. Ветка, в которой находится объект, и есть его тип метаданных.

Если у вас есть только имя объекта, используйте поиск по конфигурации (Ctrl+Shift+F с поиском по метаданным или пункт «Правка → Найти» в дереве конфигурации). Для быстрого перехода к объекту по имени удобна команда «Найти в дереве метаданных» из контекстного меню.

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

Программное определение через ТипЗнч и Тип

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

Если ТипЗнч(Значение) = Тип("СправочникСсылка.Номенклатура") Тогда

// Это ссылка на справочник Номенклатура

КонецЕсли;

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

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

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

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

ИмяОбъекта = МД.Имя; // например, "Номенклатура"

ПолноеИмя = МД.ПолноеИмя(); // "Справочник.Номенклатура"

ВидМетаданных = МД.Родитель().Имя; // "Справочники"

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

Если Метаданные.Справочники.Содержит(Ссылка.Метаданные()) Тогда

// Значение — ссылка на любой справочник

ИначеЕсли Метаданные.Документы.Содержит(Ссылка.Метаданные()) Тогда

// Значение — ссылка на любой документ

КонецЕсли;

Метод НайтиПоТипу() работает в обратную сторону: по типу значения возвращает объект описания метаданных или Неопределено, если тип не связан с прикладным объектом:

МД = Метаданные.НайтиПоТипу(ТипЗнч(Значение));

Если МД = Неопределено Тогда

// Примитивный тип или объект, не связанный с метаданными

КонецЕсли;

bsl
Функция ВидМетаданныхСсылки(Ссылка) Экспорт
	МД = Ссылка.Метаданные();
	Если Метаданные.Справочники.Содержит(МД) Тогда
		Возврат "Справочник";
	ИначеЕсли Метаданные.Документы.Содержит(МД) Тогда
		Возврат "Документ";
	ИначеЕсли Метаданные.ПланыВидовХарактеристик.Содержит(МД) Тогда
		Возврат "ПланВидовХарактеристик";
	Иначе
		Возврат "Прочее";
	КонецЕсли;
КонецФункции

Определение типа через запрос

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

ВЫБРАТЬ

Реализация.Контрагент КАК Контрагент

ГДЕ

ТИПЗНАЧЕНИЯ(Реализация.Контрагент) = ТИП(Справочник.Контрагенты)

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

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

Конфигуратор

Подходит для разовой проверки при разработке; не работает в пользовательском режиме

ТипЗнч + Тип

Быстрая проверка на конкретный тип; неудобна для определения вида метаданных в целом

Метаданные() ссылки

Универсальный способ получить вид, имя и свойства объекта; требует наличия ссылки

Запрос ТИПЗНАЧЕНИЯ

Эффективен при отборах по составным типам; работает только со ссылочными типами

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

Частая ошибка — попытка вызвать Метаданные() у значения примитивного типа или у объекта, а не ссылки. У чисел, строк и дат этого метода нет, поэтому перед вызовом проверяйте, что значение ссылочного типа. Универсальная проверка — через Метаданные.НайтиПоТипу(): если вернул Неопределено, значение не является прикладным объектом.

Вторая ошибка — путаница между типом значения и видом метаданных. Сравнение ТипЗнч(Ссылка) = Тип("СправочникСсылка") невозможно, такого обобщённого типа не существует: тип всегда привязан к конкретному объекту конфигурации.

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

Типичные ошибки
01
Вызов Метаданные() у примитивного значения — приводит к ошибке выполнения; сначала проверяйте тип через НайтиПоТипу()
02
Сравнение с несуществующим обобщённым типом СправочникСсылка — используйте Метаданные.Справочники.Содержит()
03
Проверка вида по строковому имени родителя — хрупко при переименовании; надёжнее метод Содержит()
04
Попытка определить вид регистра по записи через ТипЗнч — у регистров нет ссылок, анализируйте тип набора записей или менеджера регистра

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

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

Для отладки удобно выводить ПолноеИмя() метаданных в журнал регистрации или сообщение — это даёт однозначную идентификацию объекта вида «Документ.РеализацияТоваровУслуг».

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

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

Проверка на ссылке справочника
Норма

Метаданные().ПолноеИмя() начинается со слова Справочник

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

Ошибка выполнения или Неопределено

Проверка на примитивном значении
Норма

НайтиПоТипу вернул Неопределено, ветка обработана

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

Вызван метод Метаданные() и возникло исключение

Пустая ссылка
Норма

Тип определяется корректно, отдельно проверяется заполненность

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

Пустая ссылка обрабатывается как реальный объект

Практический порядок выбора способа

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

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

Как выбрать действие

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

Часто задаваемые вопросы

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

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

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

Регистры не имеют ссылочного типа. Анализируйте тип менеджера или набора записей: ТипЗнч(НаборЗаписей) даст, например, РегистрСведенийНаборЗаписей.ИмяРегистра, а через Метаданные.НайтиПоТипу() можно получить описание самого регистра.

Можно ли получить список всех объектов нужного вида?

Да. Переберите коллекцию метаданных в цикле: Для Каждого Объект Из Метаданные.Документы Цикл — внутри цикла доступны имя, синоним и свойства каждого документа конфигурации.

Почему НайтиПоТипу() возвращает Неопределено?

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

Работают ли эти методы в мобильной платформе и внешних обработках?

Базовые функции ТипЗнч(), Тип() и объектная модель метаданных доступны во всех режимах исполнения, включая внешние обработки. Ограничения могут касаться только состава метаданных, доступных в конкретной поставке мобильного приложения.

Итог

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

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