К сожалению, в платформе 1С8 нет возможности выполнять запросы к метаданным.
А при анализе конфигурации порой хочется получить список всех справочников или всех реквизитов документов, которые содержат определенный тип.
Для таких целей программисты обычно пишут обход дерева метаданных.
Я тоже так раньше делал, но потом написал универсальную функцию обхода дерева.
Она не слишком шустрая, т.к. использует команду « Выполнить » для отбора результата, но в таких задачах шустрость не всегда нужна.
Вот код функции, обходящей метаданные:
Функция ОбойтиМетаданные (П, Код)
//Обходит метаданные, выбирая код отбора.
Для Каждого Класс ИЗ МДКласc Цикл
ОбойтиМетаданныеСлуж(П, Описание, Код);
Если П.Пропустить Тогда
Если Класс=”Константы” Тогда
Для Каждого МДАтрибут ИЗ Метаданные.Константы Цикл
ОбойтиМетаданныеСлуж(П, Описание, Код);
Для Каждого МДВид ИЗ Метаданные[Класс] Цикл
Описание.Вставить (“Вид”, МДВид.Имя );
Описание.Вставить (“Уровень”, “Вид”);
Описание.Вставить (“Синоним”, МДВид.Синоним );
ОбойтиМетаданныеСлуж (П, Описание, Код);
Если П.Пропустить Тогда
Для Каждого МДАтрибут ИЗ МДВид.Реквизиты Цикл
Описание.Вставить (“Уровень”, “Атрибут”);
Описание.Вставить (“Атрибут”, МДАтрибут.Имя );
Описание.Вставить (“Синоним”, МДАтрибут.Синоним );
Описание.Вставить (” ТипАтрибута “, МДАтрибут.Тип );
Описание.Вставить (” ВидАтрибута “, “Реквизит”);
ОбойтиМетаданныеСлуж (П, Описание, Код);
Для Каждого МДАтрибут ИЗ МДВид.Измерения Цикл
Описание.Вставить (“Уровень”, “Атрибут”);
Описание.Вставить (“Атрибут”, МДАтрибут.Имя );
Описание.Вставить (“Синоним”, МДАтрибут.Синоним );
Описание.Вставить (” ТипАтрибута “, МДАтрибут.Тип );
Описание.Вставить (” ВидАтрибута “, “Измерение”);
ОбойтиМетаданныеСлуж (П, Описание, Код);
Для Каждого МДАтрибут ИЗ МДВид.Ресурсы Цикл
Описание.Вставить (“Уровень”, “Атрибут”);
Описание.Вставить (“Атрибут”, МДАтрибут.Имя );
Описание.Вставить (“Синоним”, МДАтрибут.Синоним );
Описание.Вставить (” ТипАтрибута “, МДАтрибут.Тип );
Описание.Вставить (” ВидАтрибута “, “Ресурс”);
ОбойтиМетаданныеСлуж (П, Описание, Код);
Функция ОбойтиМетаданныеСлуж(П, Описание, Код)
Если Р = истина Тогда
П – это пустая структура, в нее в будет добавлена таблица значений с результатом в поле “ТЗ”.
Код – это условие отбора записей из метаданных.
Для функции метаданные представляются как плоская таблица с колонками:
Атрибут – имя реквизита объекта (для уровня “Атрибут”)
ТипАтрибута – тип значения реквизита объекта (для уровня “Атрибут”)
ВидАтрибута – “Реквизит”, “Измерение”, “Ресурс” (для уровня “Атрибут”)
Синоним – синоним текущего метаданного , если он задан (для уровня “Вид” или “Атрибут”)
Уровень – уровень текущей записи, т.е. что описывает текущая запись “Класс”, “Вид” или “Атрибут”
Т.е., по сути, метаданные рассматриваются как иерархический справочник с уровнями иерархии: Класс, затем Вид, затем Атрибут.
Выражение для код записывается на языке 1С, где Описание – текущая запись метаданных, если в переменную Р возвращается истина, то осуществляется отбор.
Пример отбора реквизитов, содержащих тип ХранилищеЗначения :
Код = “Р = Описание.Уровень = “”Атрибут”” И Описание.ТипАтрибута.СодержитТип(Тип(“”ХранилищеЗначения””))”;
Пример получения списка всех справочников:
Код = “Р = Описание.Уровень = “”Вид”” И Описание.Класс = “Справочники”;
Запрос к метаданным использован также в следующих моих разработках:
· Проверка размера данных в хранилищах значений
· Анализ прав доступа
Конечно, обработку можно ускорить, избавиться от В ыполнить , но пока и в таком виде она неплохо справляется.
Как видно, не все объекты метаданных поддерживаются, например, нет бизнес-процессов, но основные типы есть, остальные можно прикрутить. 😉
Будут идеи – пишите, а может берите, и подтачивайте под свои нужды, а потом шлите мне исправления. Если что, опубликую.
Область применения: управляемое приложение, мобильное приложение, обычное приложение.
1. В тех случаях, когда известен тип объекта метаданного (справочник, документ, и т.п.), то получение метаданных объекта конфигурации следует выполнять с помощью метода Метаданные этого объекта (или ссылки для объектов ссылочного типа), а не путем обращения к свойству глобального контекста Метаданные , так как второй способ существенно более медленный.
2. В тех случаях, когда тип объекта метаданного заранее неизвестен, рекомендуется воспользоваться методом НайтиПоТипу , например:
// Получить полное имя объекта метаданных вида “Справочник.Номенклатура”, “Документ.ПриходнаяНакладная” по переданной ссылке.
ИмяОбъектаМетаданного = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя();
При написании небольших автоматизированных тестов часто надо обойти всю конфигурацию и проверить, например, для всех форм какое-нибудь свойство. Это всё легко делается через свойство глобального контекста “Метаданные”, но чтоб дорбаться до обхода реквизитов надо написать кучу вложенных циклов. При этом код становится слабочитаемым и слабомодифицируемым.
Ниже приведен небольшой модуль, который решает задачу легко и удобно. Создана специальная функция РазвернутьСтрокуОбходаМетаданных, которая может по строке типа “Метаданные.Справочники.*.Реквизиты.*” построить массив строк с перечислением всех реквизитов всех справочников. При помощи этой и нескольких других функций в экспортных функциях модуля реализованы вполне прикладные задачи – получение всех реквизитов, всех макетов, всех форм конфигурации и построение таблицы всех составных типов.