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