Когда я начал делать обработку по анализу расширений, я думал, что на это уйдет не так много времени. Но в итоге это был долгий и интересный для меня путь.
Вот что у меня получилось.

- С левой стороны обработки указаны все метаданные конфигурации, при нажатии на плюсик, происходит раскрытие и заполнение нужных строк.
- Если необходимо, можно нажать "анализ всей конфигурации" и будет заполнено все дерево, сказанием, какие объекты были изменены в расширениях или добавлены в них.
- Справа вверху можно выбрать, какие расширения требуется проанализировать, выбрать их и нажать "Анализ изменений выбранных расширений" и после анализа, в левой части в колонке "Список расширений", будут список расширений, где они есть через точку с запятой.
- Чтобы быстро посмотреть только те объекты, которые присутствуют в выбранных расширениях предназначена правая нижняя часть.
Я не знаю, как узнать, были изменения объекта в расширении, или оно только присутствует для ссылок, но для меня было достаточно именно присутствия в расширении, для последующего анализа и принятия решения, куда вносить доработки.
Что я делал, и с чем столкнулся.
1. Мне надо было получить список расширений, которые есть в информационной базе.
Для этого много времени не потребовалось, и это было хорошее начало.
Сложность возникла, когда я решил пропустить патчи, но с этим я тоже справился.
&НаСервере
Процедура ЗаполнитьСписокРасширенийНаСервере()
//получим список всех расширений в конфигурации
МассивРасширений = РасширенияКонфигурации.Получить();
Объект.СписокРасширений.Очистить();
Для каждого ТекРасширение Из МассивРасширений Цикл
//пропустим исправления
Если Объект.СкрыватьИсправления Тогда
Если ТекРасширение.Назначение = Метаданные.СвойстваОбъектов.НазначениеРасширенияКонфигурации.Исправление Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
НоваяСтрокаРасширения = Объект.СписокРасширений.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрокаРасширения,ТекРасширение);
КонецЦикла;
КонецПроцедуры
2. Дальше надо было сделать дерево метаданных, и это я думал простыми циклами по метаданным можно выполнить, но оказалось, что это совсем не так, ну или моих знаний для этого не хватает.
какие были сложности:
- Не все картинки дерева метаданных есть в библиотеке картинок
- Есть группа общие, которых по сути нет в метаданных
- Подсистемы могут быть подчинены сами себе
- У разных объектов разный набор сущностей метаданных
- При заполнении дерева метаданных в момент открытия обработка зависала, для заполнения всех сущностей.
В итоге, часть картинок менял на подобные или логичные, а какие-то делал в виде двоичных данных в макетах.
Алгоритм для общие был свой, для подсистем были особенности, для хранения сущностей сделал макет.
А в момент открытия заполнял только первый уровень.
Для структуры метаданных я в итоге сделал макет, который считывал в момент открытия

И при открытии обработки делал заполнение
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
НазваниеСтрокиЗаглушки = "Здесь позже будут объекты метаданных.";
//дадим название и первоначально заполним структуру метаданных
Элементы.ГруппаДереваМетаданных.Заголовок = Метаданные.Синоним;
//в этой таблице перечислены все элементы, которые могут быть у объектов метаданных
ОписаниеВариантовПолейМетаданных.Очистить();
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "Измерения"; НоваяСтр.Картинка = БиблиотекаКартинок.Измерение;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "Ресурсы"; НоваяСтр.Картинка = БиблиотекаКартинок.Ресурс;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "РеквизитыАдресации"; НоваяСтр.Картинка = БиблиотекаКартинок.Реквизит;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "Реквизиты"; НоваяСтр.Картинка = БиблиотекаКартинок.Реквизит;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "ПризнакиУчета"; НоваяСтр.Картинка = БиблиотекаКартинок.Реквизит;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "ПризнакиУчетаСубконто"; НоваяСтр.Картинка = БиблиотекаКартинок.Реквизит;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "Перерасчеты"; НоваяСтр.Картинка = БиблиотекаКартинок.Перечитать;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "Графы"; НоваяСтр.Картинка = БиблиотекаКартинок.КонструкторЗапросаВременнаяТаблица;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "ЗначенияПеречисления"; НоваяСтр.Картинка = БиблиотекаКартинок.Реквизит;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "ТабличныеЧасти"; НоваяСтр.Картинка = БиблиотекаКартинок.ВложеннаяТаблица;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "Формы"; НоваяСтр.Картинка = БиблиотекаКартинок.Форма;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "Команды"; НоваяСтр.Картинка = БиблиотекаКартинок.СформироватьОтчет;
НоваяСтр = ОписаниеВариантовПолейМетаданных.Добавить();
НоваяСтр.Название = "Макеты"; НоваяСтр.Картинка = БиблиотекаКартинок.ТабличныйДокументОтображатьЗаголовки;
ВнесениеСтруктурыДерева(ДеревоМетаданных);
КонецПроцедуры
&НаСервере
//добавление самого верхнего уровня структуры метаданных
//элементы хранятся в макете СтруктураМетаданных
Процедура ВнесениеСтруктурыДерева(ДеревоМетаданных)
ВерхнийУровеньМетаданных = ДеревоМетаданных.ПолучитьЭлементы();
Если ВерхнийУровеньМетаданных.Количество() <> 0 Тогда
//там уже что-то есть
Возврат;
КонецЕсли;
//создадим список элементов, для отображения на форме только элементы верхнего уровня, чтобы форма досточно быстро открылась
ЗаполнитьСтруктуруМетаданных("СтруктураМетаданных");
СтрокиКорневогоУровня = ОписаниеСтруктурМетаданных.НайтиСтроки(Новый Структура("РодительЭлементов",""));
Для каждого УровеньМедатанных Из СтрокиКорневогоУровня Цикл
ТекущийЭлементДерева = ВерхнийУровеньМетаданных.Добавить();
ТекущийЭлементДерева.Объект = УровеньМедатанных.Название;
ТекущийЭлементДерева.Картинка = УровеньМедатанных.Картинка;
ТекущийЭлементДерева.ИмяМетаданных = УровеньМедатанных.ИмяОбъектаМетаданных;
//если не будет элементов метаданных, то даже заглушку не будет добавлять
НадоДобавлятьЗаглушку = Истина;
Если ЗначениеЗаполнено(ТекущийЭлементДерева.ИмяМетаданных) Тогда
Если Метаданные[ТекущийЭлементДерева.ИмяМетаданных].Количество() = 0 Тогда
НадоДобавлятьЗаглушку = Ложь;
КонецЕсли;
КонецЕсли;
Если НадоДобавлятьЗаглушку Тогда
ПодчиненныйЭлемент = ТекущийЭлементДерева.ПолучитьЭлементы().Добавить();
ПодчиненныйЭлемент.Объект = НазваниеСтрокиЗаглушки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаСервере
//получаемт по данным макета таблицу значений с объектами метаданных
Процедура ЗаполнитьСтруктуруМетаданных(НазваниеМакета)
ОписаниеСтруктурМетаданных.Очистить(); //получаем пустую ТЗ
МакетДереваМетаданных = РеквизитФормыВЗначение("Объект").ПолучитьМакет(НазваниеМакета);
//В макете есть названия элементов дерева и картинки
Для Ном = 2 По МакетДереваМетаданных.ВысотаТаблицы Цикл
//проверим заполненность названия элемента
НазваниеЭлемента = МакетДереваМетаданных.Область(Ном,2,Ном,2).Текст;
Если Не ЗначениеЗаполнено(НазваниеЭлемента) Тогда
//если названия нет, тогда идем дальше
Продолжить;
КонецЕсли;
РодительЭлементов = МакетДереваМетаданных.Область(Ном,1,Ном,1).Текст;
ИмяОбъектаМетаданных = МакетДереваМетаданных.Область(Ном,4,Ном,4).Текст;
//проверим, есть ли вообще такие метаданные, вдруг в разных версиях платформы что-то работает по разному
Если ЗначениеЗаполнено(ИмяОбъектаМетаданных) Тогда
Попытка
ЕстьМетаданные = Метаданные[ИмяОбъектаМетаданных];
Успешно = Истина;
Исключение
Успешно = Ложь;
КонецПопытки;
Если Не Успешно Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
//получим картинку для отображения
НазваниеКартинки = МакетДереваМетаданных.Область(Ном,3,Ном,3).Текст;
Если СтрНайти(НазваниеКартинки,"Макет") > 0 Тогда
//если это не стандартная картинка, а двоичные данные из макета
//Уберем из названия слово макет
КартинкаДляВставки = КартинкаИзМакета(СтрЗаменить(НазваниеКартинки,"Макет.",""));
ИначеЕсли Не ЗначениеЗаполнено(НазваниеКартинки) Тогда
КартинкаДляВставки = Неопределено;
Иначе
КартинкаДляВставки = БиблиотекаКартинок[НазваниеКартинки];
КонецЕсли;
НоваяСтр = ОписаниеСтруктурМетаданных.Добавить();
НоваяСтр.РодительЭлементов = РодительЭлементов;
НоваяСтр.Картинка = КартинкаДляВставки;
НоваяСтр.Название = НазваниеЭлемента;
НоваяСтр.ИмяОбъектаМетаданных = МакетДереваМетаданных.Область(Ном,4,Ном,4).Текст;
//это можно сделать через цикл список элементов, котоыре в таблице
НомерКолонки = 5;
ЕстьПодиченныеЭлементы = Ложь;
Для каждого Стр Из ОписаниеВариантовПолейМетаданных Цикл
Если МакетДереваМетаданных.Область(Ном,НомерКолонки,Ном,НомерКолонки).Текст="Да" Тогда
НоваяСтр[Стр.Название] = Истина;
ЕстьПодиченныеЭлементы = Истина;
Иначе
НоваяСтр[Стр.Название] = Ложь;
КонецЕсли;
НомерКолонки = НомерКолонки+1;
КонецЦикла;
НоваяСтр.ЕстьПодчиненные = ЕстьПодиченныеЭлементы;
//так было без списка элементов
//НоваяСтр.Ресурсы = ?(МакетДереваМетаданных.Область(Ном,5,Ном,5).Текст="Да",Истина,Ложь);
//НоваяСтр.РеквизитыАдресации = ?(МакетДереваМетаданных.Область(Ном,6,Ном,6).Текст="Да",Истина,Ложь);
//НоваяСтр.Реквизиты = ?(МакетДереваМетаданных.Область(Ном,7,Ном,7).Текст="Да",Истина,Ложь);
//НоваяСтр.ПризнакиУчета = ?(МакетДереваМетаданных.Область(Ном,8,Ном,8).Текст="Да",Истина,Ложь);
//НоваяСтр.ПризнакиУчетаСубконто = ?(МакетДереваМетаданных.Область(Ном,9,Ном,9).Текст="Да",Истина,Ложь);
//НоваяСтр.Перерасчеты = ?(МакетДереваМетаданных.Область(Ном,10,Ном,10).Текст="Да",Истина,Ложь);
//НоваяСтр.Графы = ?(МакетДереваМетаданных.Область(Ном,11,Ном,11).Текст="Да",Истина,Ложь);
//НоваяСтр.ЗначенияПеречисления = ?(МакетДереваМетаданных.Область(Ном,12,Ном,12).Текст="Да",Истина,Ложь);
//НоваяСтр.ТабличныеЧасти = ?(МакетДереваМетаданных.Область(Ном,13,Ном,13).Текст="Да",Истина,Ложь);
//НоваяСтр.Формы = ?(МакетДереваМетаданных.Область(Ном,14,Ном,14).Текст="Да",Истина,Ложь);
//НоваяСтр.Команды = ?(МакетДереваМетаданных.Область(Ном,15,Ном,15).Текст="Да",Истина,Ложь);
//НоваяСтр.Макеты = ?(МакетДереваМетаданных.Область(Ном,16,Ном,16).Текст="Да",Истина,Ложь);
КонецЦикла;
КонецПроцедуры // ПолучитьСтруктуруМетаданных()
3. В момент раскрытия объектов в дереве, я анализировал метаданные и заполнял только те, которые использовались, т.е. если по сути макеты могут быть, но их фактически нет, я эти строку уже не добавлял. таким образом уменьшал количество строк и ускорял работу обработки.
4. В метаданных есть несколько методов для анализа расширений.
ЕстьИзмененияРасширениямиКонфигурации() - дает только булево - есть изменения или нет.
РасширениеКонфигурации() - каким расширением добавлен данный объект.
С их помощью удалось заполнить сам факт изменения в расширениях
//сделаем анализ расширений
ТекСтрока.НаличиеИзмененийВРасширениях = ЭлементМетаданных.ЕстьИзмененияРасширениямиКонфигурации();
//можеть быть объект полностью добавлен
РасширениеКотороеЕгоДобавило = ЭлементМетаданных.РасширениеКонфигурации();
Если РасширениеКотороеЕгоДобавило = Неопределено Тогда
Иначе
ТекСтрока.НаличиеИзмененийВРасширениях = Истина;
ТекСтрока.СписокРасширений = "Добавлено "+РасширениеКотороеЕгоДобавило.Имя+"; ";
ТекСтрока.СписокВыбранныхРасширений.Добавить(РасширениеКотороеЕгоДобавило.Имя);
КонецЕсли;
5. Для получения метаданных расширения приходилось загружать их каждый раз, и на это требуется достаточно много времени.
Для каждого Стр Из Объект.СписокРасширений Цикл
Если НЕ Стр.Выбран Тогда
Продолжить;
КонецЕсли;
//получим метаданные расширения
МассивРасширений = РасширенияКонфигурации.Получить(Новый Структура("Имя",Стр.Имя));
Если МассивРасширений.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
МетаданныеРасширения = Новый ОбъектМетаданныхКонфигурация(МассивРасширений[0].ПолучитьДанные());
АнализИзмененийВРасширении(МетаданныеРасширения,Стр.Имя);
КонецЦикла;
Все остальное не так интересно, больше уделял внимание тестированию и улучшению взаимодействия с пользователем.
Обработка должна работать в любой конфигурации на управляемых формах.
Я допускаю, что что-то не учел, и если будет спрос, я готов учесть замечания и делать новые версии этой обработки.
Проверено на следующих конфигурациях и релизах:
- Зарплата и управление персоналом КОРП, редакция 3.1, релизы 3.1.37.16
- Бухгалтерия предприятия, редакция 3.0, релизы 3.0.195.36
Вступайте в нашу телеграмм-группу Инфостарт