Как в 1С определить тип типа и проверить его принадлежность к справочникам

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

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

В этой статье мы подробно разберем, как эффективно классифицировать типы в 1С:Предприятии 8, рассмотрим стандартные методы платформы и изучим продвинутые способы работы с метаданными.

Метод 1: Использование глобального метода ТипВсеСсылки

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

Проанализируем пример кода, который позволяет проверить принадлежность типа:


// Допустим, НужныйТип получен из ПВХ или ОписанияТипов
НужныйТип = ТипЗнч(Объект.Ссылка); // Для примера

Если Справочники.ТипВсеСсылки().СодержитТип(НужныйТип) Тогда
    Сообщить("Это тип справочника!");
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(НужныйТип) Тогда
    Сообщить("Это тип документа!");
КонецЕсли;

Важный нюанс: Этот способ работает только для ссылочных типов. Если вы попытаетесь проверить таким образом тип самого объекта (например, СправочникОбъект.Номенклатура), проверка вернет Ложь, так как ТипВсеСсылки() содержит только ссылки (CatalogRef).

Метод 2: Определение конкретного объекта через Метаданные.НайтиПоТипу

Если нам недостаточно знать, что это «какой-то справочник», а нужно получить доступ к его метаданным (имени, синониму, реквизитам), следует использовать метод Метаданные.НайтиПоТипу(). Это наиболее профессиональный и точный подход.

Разберем, как это работает на практике:


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

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

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

Метод 3: Работа с составными типами через ОписаниеТипов

В Планах видов характеристик свойство ТипЗначения обычно возвращает не один тип, а объект ОписаниеТипов. Он может быть составным, то есть содержать массив разрешенных типов. Чтобы правильно обработать такую ситуацию, нам нужно проанализировать каждый тип в отдельности.

Выясним, как извлечь и проверить все типы из описания:


Описание = ПВХ_Ссылка.ТипЗначения;
МассивТипов = Описание.Типы();

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

Метод 4: Быстрая идентификация через XML-сериализацию

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

Посмотрим на пример анализа строки:


ТипXML = XMLТип(НужныйТип);
// Для справочников ИмяТипа будет иметь вид "CatalogRef.ИмяСправочника"
Если Найти(ТипXML.ИмяТипа, "CatalogRef") > 0 Тогда
    ИмяСправочника = Сред(ТипXML.ИмяТипа, Найти(ТипXML.ИмяТипа, ".") + 1);
    Сообщить("Найден справочник через XML: " + ИмяСправочника);
КонецЕсли;

Этот метод опирается на строковое представление, поэтому его стоит использовать с осторожностью, понимая специфику именования типов в XML-сериализации 1С.

Резюме и рекомендации

Подводя итог, проанализируем, какой метод выбрать в зависимости от ситуации:

  1. Если нужно просто отфильтровать справочники от других типов — используйте Справочники.ТипВсеСсылки().СодержитТип(НужныйТип).
  2. Если нужно узнать имя справочника и работать с его структурой — используйте Метаданные.НайтиПоТипу(НужныйТип).
  3. Если вы работаете с составными типами в ПВХ — всегда сначала вызывайте метод Типы() у объекта ОписаниеТипов.
  4. Для получения полного имени метаданных (строкой) удобнее всего использовать ОбъектМетаданных.ПолноеИмя() после поиска по типу.

Помните, что попытка вызвать метод Вид() у объекта типа Тип приведет к ошибке, так как этот метод предназначен для некоторых видов значений в старых версиях или специфических контекстах, но не для системного объекта Тип в 1С 8.x.

← На главную