Как получить тип ссылки и имя метаданных в формате «Документ.Имя» или «Справочник.Имя» в 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

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

Способ 1. Прямой вызов метода ПолноеИмя() через объект метаданных ссылки

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

Посмотрим на пример использования:


Если Значение <> Неопределено И Значение <> NULL Тогда
    ПолноеИмяОбъекта = Значение.Метаданные().ПолноеИмя();
    Сообщить(ПолноеИмяОбъекта); // Выведет, например: "Документ.ПеремещениеТоваров"
КонецЕсли;

Проанализируем преимущества этого подхода:

  1. Высокая производительность: операция не формирует SQL-запросов к базе данных. Платформа берет сведения из дерева метаданных конфигурации, которое уже загружено в оперативную память.
  2. Универсальность: метод корректно определяет любые ссылочные типы конфигурации — справочники, документы, планы счетов, планы видов характеристик, задачи и отчеты.
  3. Корректная работа с «битыми» ссылками: если объект был удален из базы данных и ссылка отображается как <Объект не найден>, метод Значение.Метаданные().ПолноеИмя() все равно отработает без ошибок, так как идентификатор типа метаданных сохраняется в структуре самой ссылки.

Ограничения прямого метода и правила безопасного вызова

Рассмотрим ситуации, в которых попытка прямого вызова Значение.Метаданные() может вызвать аварийное завершение программы:

  1. Поле не заполнено: если реквизит составного типа очищен, он содержит значение Неопределено (или NULL при чтении из запроса). Попытка вызвать метод у такого значения вызовет исключение «Метод объекта не обнаружен». Обратите внимание, что стандартная проверка через ЗначениеЗаполнено() здесь не всегда уместна: пустая ссылка (например, Документы.ПеремещениеТоваров.ПустаяСсылка()) вернет Ложь, но при этом обладает типом и метаданными. Поэтому проверять нужно именно на равенство Неопределено и NULL.
  2. Контекст выполнения (клиент/сервер): в обычном приложении и толстом клиенте метод доступен повсеместно. Однако в управляемом приложении (тонкий и веб-клиент) метод Метаданные() у ссылок недоступен. В управляемых формах эту операцию обязательно следует выполнять на сервере.

Способ 2. Безопасный поиск метаданных по типу значения

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


ТипЗначения = ТипЗнч(Значение);
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗначения);

Если ОбъектМетаданных <> Неопределено Тогда
    ПолноеИмяОбъекта = ОбъектМетаданных.ПолноеИмя();
    Сообщить("Выбран ссылочный объект: " + ПолноеИмяОбъекта);
Иначе
    Сообщить("Выбрано значение примитивного типа или неопределенный тип");
КонецЕсли;

Этот способ полностью безопасен: если в Значение передан примитивный тип или Неопределено, метод НайтиПоТипу просто вернет Неопределено, не вызывая исключений в коде.

Способ 3. Проверка принадлежности ссылки к конкретному классу метаданных

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


ТипПроверяемого = ТипЗнч(Значение);

Если Метаданные.Справочники.ТипВсеСсылки().СодержитТип(ТипПроверяемого) Тогда
    // Обработка логики для любого справочника
    Имя = "Справочник." + Значение.Метаданные().Имя;
ИначеЕсли Метаданные.Документы.ТипВсеСсылки().СодержитТип(ТипПроверяемого) Тогда
    // Обработка логики для любого документа
    Имя = "Документ." + Значение.Метаданные().Имя;
КонецЕсли;

Метод ТипВсеСсылки().СодержитТип() позволяет проверить принадлежность типа всей ветке метаданных целиком без перебора конкретных объектов в цикле.

Способ 4. Использование сериализатора XDTO

В системных механизмах обмена данными и веб-сервисах иногда применяется вызов сериализатора XDTO:


ТипXDTO = СериализаторXDTO.XMLТипЗнч(Значение);
Если ТипXDTO <> Неопределено Тогда
    Сообщить(ТипXDTO.ИмяТипа); // Например: "DocumentRef.ПеремещениеТоваров"
КонецЕсли;

Следует учитывать важный нюанс: свойство ИмяТипа формируется по правилам схемы XML. Имена классов здесь всегда выводятся на английском языке с постфиксом Ref (например, CatalogRef или DocumentRef). Для получения русскоязычного наименования метаданных формата 1С этот способ требует дополнительного разбора и сопоставления строк, поэтому для повседневных прикладных задач рекомендуется использовать вызов ПолноеИмя().

← На главную