Анализ использования метаданных в расширениях

29.12.21

Разработка - Механизмы платформы 1С

Готовый шаблон кода для быстрого анализа использования метаданных в расширениях.

Добрый день, коллеги.

Так уж случилось, что в наследство досталась конфигурация, в которой подрядчик наклепал 36 своих расширений. Разработка подрядчиком велась долго, программисты менялись, архитектора на проекте не было. Как следствие продукт на выходе получился с очень большой головной болью в виде расширений, причем новые реквизиты объекта метаданных добавлялись как в основную конфигурацию так и 1-2 и более расширений.

Естественно, на продакте начались серьезные проблемы как с производительностью, так и частые падения кеша  + масса багов при компиляции модулей. В итоге бороться с этим кошмаром можно только переписав все расширения в основную конфигурацию, перегрузив данные из таблиц расширений ит.д. 

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

Немного покопавшись в теории, информации на форуме родился простой код, который позволяет это сделать быстро и безболезненно. Код в этой статье представлен в качестве примера и носит показательный характер. При этом он вполне рабочий.
Цель статьи - предоставить коллегам, столкнувшимся с подобным мракобесием, готовый шаблон кода, выдающий таблицу значений с анализом. Возможно, кому-то пригодится.

Пример кода анализа всех расширений по метаданным на примере "Документов":
 

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

 

Метаданных в расширениях шаблон кода

См. также

Сервисы интеграции без Шины и интеграции

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    2649    dsdred    16    

59

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    6125    dsdred    59    

86

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    6029    YA_418728146    25    

68

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    7122    dsdred    36    

113

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    19230    SeiOkami    46    

119

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12943    human_new    27    

76

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    9547    YA_418728146    6    

143

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6575    sebekerga    54    

95
Отзывы
6. Yashazz 4727 03.01.22 15:27 Сейчас в теме
Остальные комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ITSun 29.12.21 09:50 Сейчас в теме
По моему скромному мнению, было бы хорошо прикрепить к статье какую-либо наглядную визуализацию анализа помимо таблицы.
2. Восьмой 88 29.12.21 10:43 Сейчас в теме
(1) В ближайшее время выложу полноценную обработку, а сейчас это именно шаблон кода.
3. Evg-Lylyk 4622 29.12.21 10:55 Сейчас в теме
Здоровы бы было занести добавление строки в процедуру
https://paste1c.ru/4llz4lvtsi7f
стало бы короче и понятней
4. Восьмой 88 29.12.21 11:46 Сейчас в теме
(3) Коллеги всему свое время, сейчас это шаблон кода, макет так сказать - ядра будущей обработки.
5. tigcorp 3 29.12.21 20:19 Сейчас в теме
В качестве затеи под дальнейшую разработку. Можно еще обходить ЭлементМетаданныхРасширения.Формы
6. Yashazz 4727 03.01.22 15:27 Сейчас в теме
7. Vasvas05 22 28.01.24 23:52 Сейчас в теме
//----------
			ОсновнойОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(СтрокаТаблицыМетаданных.ПолноеИмяМетаданных);
			Если ОсновнойОбъектМетаданных = Неопределено Тогда
				СтрокаТаблицыМетаданных.ОбъектДобавленЧерезРасширение = Истина;
			Иначе
				СтрокаТаблицыМетаданных.ОбъектДобавленЧерезРасширение = (ОсновнойОбъектМетаданных.РасширениеКонфигурации();
			КонецЕсли;
Показать

правильно будет
//----------
			ОсновнойОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(СтрокаТаблицыМетаданных.ПолноеИмяМетаданных);
			Если ОсновнойОбъектМетаданных = Неопределено Тогда
				СтрокаТаблицыМетаданных.ОбъектДобавленЧерезРасширение = Истина;
			Иначе
				СтрокаТаблицыМетаданных.ОбъектДобавленЧерезРасширение = (ОсновнойОбъектМетаданных.РасширениеКонфигурации()<>Неопределено);
			КонецЕсли;
			//----------
Показать
Восьмой; +1 Ответить
8. cdiamond 233 01.02.24 09:19 Сейчас в теме
Естественно, на продакте начались серьезные проблемы как с производительностью, так и частые падения кеша + масса багов при компиляции модулей.


Какие ваши доказательства? Ничего подобного не наблюдается на клиентских ERP где > 50 расширений с дополнением хранимых данных. На производительность это даже теоретически влиять не может, т.к. расширение создает новую таблицу СУБД заместо таблицы основной конфигурации (очищая его).
Во Фреше это вообще единственный метод доработки и добавления регистров. Не нужно вводить в заблуждение начинающих архитекторов о вредности большого количества расширений. Если они функционально разделены то это упрощает сопровождение.
Единственная проблема расширений с добавленными регистрами и реквизитами - это то что данные в расширениях иногда могут помешать обновлению, встречались ошибки реструктуризации, лечилось только полным удалением расширения. Но тогда встает задача выгрузить все данные расширений в файл и после обновления вернуть все назад на место.
9. Восьмой 88 03.02.24 19:19 Сейчас в теме
(8) Коллега Вам делать нечего как поднимать тему 21 года?
Мои доказательства плохо сделанная работа от франчей где в 10 расширениях по разному ломали один и тот-же объект как с изменением кода так и с модификацией таблиц данных на технологиях того времени.
Статья как раз была посвящена тому как бездумное и без системное клепания кучи расширений без архитекторского надзора приводит к серьезным последствиям.
Оставьте свое сообщение