При разработке сложных механизмов, таких как работа с дополнительными реквизитами в Планах видов характеристик (ПВХ), часто возникает задача программного анализа типов данных. Основная сложность заключается в том, что нам нужно работать не с конкретным значением (ссылкой), а с самим объектом Тип. Например, требуется быстро определить, является ли выбранный в ПВХ тип справочником, и если да, то каким именно, не прибегая к ресурсоемкому перебору всей коллекции метаданных.
В этой статье мы подробно разберем, как эффективно классифицировать типы в 1С:Предприятии 8, рассмотрим стандартные методы платформы и изучим продвинутые способы работы с метаданными.
Рассмотрим самый быстрый и простой способ классификации типа «верхнего уровня». Если перед нами стоит задача просто понять, относится ли имеющийся тип к категории справочников, документов или перечислений, лучше всего использовать метод ТипВсеСсылки() соответствующего менеджера. Этот метод возвращает объект ОписаниеТипов, который включает в себя все возможные ссылки данной категории.
Проанализируем пример кода, который позволяет проверить принадлежность типа:
// Допустим, НужныйТип получен из ПВХ или ОписанияТипов
НужныйТип = ТипЗнч(Объект.Ссылка); // Для примера
Если Справочники.ТипВсеСсылки().СодержитТип(НужныйТип) Тогда
Сообщить("Это тип справочника!");
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(НужныйТип) Тогда
Сообщить("Это тип документа!");
КонецЕсли;
Важный нюанс: Этот способ работает только для ссылочных типов. Если вы попытаетесь проверить таким образом тип самого объекта (например, СправочникОбъект.Номенклатура), проверка вернет Ложь, так как ТипВсеСсылки() содержит только ссылки (CatalogRef).
Если нам недостаточно знать, что это «какой-то справочник», а нужно получить доступ к его метаданным (имени, синониму, реквизитам), следует использовать метод Метаданные.НайтиПоТипу(). Это наиболее профессиональный и точный подход.
Разберем, как это работает на практике:
// Получаем объект метаданных по типу
ОбъектМетаданных = Метаданные.НайтиПоТипу(НужныйТип);
Если ОбъектМетаданных <> Неопределено Тогда
// Теперь мы можем узнать полное имя, например, "Справочник.Номенклатура"
ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
Сообщить("Тип относится к объекту: " + ПолноеИмя);
// Можем проверить принадлежность к коллекции справочников
Если Метаданные.Справочники.Содержит(ОбъектМетаданных) Тогда
Сообщить("Это точно справочник с именем: " + ОбъектМетаданных.Имя);
КонецЕсли;
КонецЕсли;
Преимущество этого метода в том, что он избавляет нас от необходимости перебирать все справочники в цикле, сравнивая их типы. Платформа делает это максимально быстро на уровне внутренних индексов.
В Планах видов характеристик свойство ТипЗначения обычно возвращает не один тип, а объект ОписаниеТипов. Он может быть составным, то есть содержать массив разрешенных типов. Чтобы правильно обработать такую ситуацию, нам нужно проанализировать каждый тип в отдельности.
Выясним, как извлечь и проверить все типы из описания:
Описание = ПВХ_Ссылка.ТипЗначения;
МассивТипов = Описание.Типы();
Для Каждого ТекущийТип Из МассивТипов Цикл
М_Объект = Метаданные.НайтиПоТипу(ТекущийТип);
Если М_Объект <> Неопределено И Метаданные.Справочники.Содержит(М_Объект) Тогда
Сообщить("В списке разрешенных есть справочник: " + М_Объект.Имя);
КонецЕсли;
КонецЦикла;
Существует альтернативный, «хитрый» способ определить суть типа, не обращаясь к глобальному объекту Метаданные. Это может быть полезно в высоконагруженных циклах. Функция XMLТипЗнч() (или XMLТип() для типа) возвращает структуру, содержащую строковое описание типа в формате XML.
Посмотрим на пример анализа строки:
ТипXML = XMLТип(НужныйТип);
// Для справочников ИмяТипа будет иметь вид "CatalogRef.ИмяСправочника"
Если Найти(ТипXML.ИмяТипа, "CatalogRef") > 0 Тогда
ИмяСправочника = Сред(ТипXML.ИмяТипа, Найти(ТипXML.ИмяТипа, ".") + 1);
Сообщить("Найден справочник через XML: " + ИмяСправочника);
КонецЕсли;
Этот метод опирается на строковое представление, поэтому его стоит использовать с осторожностью, понимая специфику именования типов в XML-сериализации 1С.
Подводя итог, проанализируем, какой метод выбрать в зависимости от ситуации:
Справочники.ТипВсеСсылки().СодержитТип(НужныйТип).Метаданные.НайтиПоТипу(НужныйТип).Типы() у объекта ОписаниеТипов.ОбъектМетаданных.ПолноеИмя() после поиска по типу.Помните, что попытка вызвать метод Вид() у объекта типа Тип приведет к ошибке, так как этот метод предназначен для некоторых видов значений в старых версиях или специфических контекстах, но не для системного объекта Тип в 1С 8.x.