Получение дерева элементов обычной формы путем анализа системного представления формы (ЗначениеВСтрокуВнутр). Альтернатива деструктивному анализу
В публикации рассмотрен вариант получения дерева элементов обычной формы с учетом принадлежности элементов панелям и страницам панелей.
- Описание
- Подробнее
Описание
Основным проблемным местом в получении дерева является определение, какой панели и странице панели принадлежит элемент формы. Единственный известный мне способ, который решает данную задачу, это — декструктивный анализ формы. Ниже приведен набор процедур/функций, решающий задачу другим способом. Идею взял из публикации //sale.itcity.ru/public/57431/, функцию, преобразующую внутреннее представление формы в формат xml из этого сообщения.
Тестировал на 8.1, 8.2, 8.3 (8.3.9 включительно)
P.S. получение дерева кнопок командной панели не рассмотрено, т.к. не представляет трудности.
Функция ПолучитьДеревоЭлементовФормы(Форма)
СтрокаФормы = ЗначениеВСтрокуВнутр(Форма);
XMLСтрокаФормы = СтрокаВнутрВХМЛТело(СтрокаФормы);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(XMLСтрокаФормы);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
РазыменовательПИ = Новый РазыменовательПространствИменDOM(ДокументDOM);
СтрокаXPath = «/elem/elem/elem[1]/elem[2]/elem[2]»;
РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(СтрокаXPath, ДокументDOM,
РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
ДЗ = Новый ДеревоЗначений;
ДЗ.Колонки.Добавить(«ЭлементФормы»);
Узел = РезультатXPath.ПолучитьСледующий();
СтрокаДЗ = ДЗ.Строки.Добавить();
СтрокаДЗ.ЭлементФормы = Форма.Панель;
Если Узел <> Неопределено Тогда
ОбойтиУзел(Форма, Узел, СтрокаДЗ);
КонецЕсли;
Возврат ДЗ;
КонецФункции
Процедура ОбойтиУзел(Форма, Узел, СтрокаДЗ)
Для каждого УзелЭлФормы Из Узел.ДочерниеУзлы Цикл
Если УзелЭлФормы.ИмяУзла = «data» Тогда
Для каждого Страница Из СтрокаДЗ.ЭлементФормы.Страницы Цикл
СтрокаСтраница = СтрокаДЗ.Строки.Добавить();
СтрокаСтраница.ЭлементФормы = Страница;
КонецЦикла;
Иначе
СвойстваЭлФормы = УзелЭлФормы.ДочерниеУзлы;Если ТипЗнч(УзелЭлФормы.ПоследнийДочерний) = Тип(«ТекстDOM») Тогда
УзелЭлФормы.УдалитьДочерний(УзелЭлФормы.ПоследнийДочерний);
КонецЕсли;
ЭтоПанель = СвойстваЭлФормы[СвойстваЭлФормы.Количество() — 1].ТекстовоеСодержимое <> «0»;
СвойстваЭлФормыСИменем = СвойстваЭлФормы[СвойстваЭлФормы.Количество() — 2].ДочерниеУзлы;
СвойстваЭлФормыСИндексом = СвойстваЭлФормы[СвойстваЭлФормы.Количество() — 3].ДочерниеУзлы;
ИндексСтраницы = Число(СвойстваЭлФормыСИндексом[СвойстваЭлФормыСИндексом.Количество() — 5].ТекстовоеСодержимое);
НовСтрокаДЗ = СтрокаДЗ.Строки[ИндексСтраницы].Строки.Добавить();
НовСтрокаДЗ.ЭлементФормы = Форма.ЭлементыФормы[СтрЗаменить(СвойстваЭлФормыСИменем[1].ТекстовоеСодержимое, «»»», «»)];
Если ЭтоПанель Тогда
ОбойтиУзел(Форма, СвойстваЭлФормы[СвойстваЭлФормы.Количество() — 1], НовСтрокаДЗ);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция СтрокаВнутрВХМЛТело(вхСтрока) Экспорт
выхХМЛТело = СтрЗаменить(вхСтрока,Символы.ПС,«»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,Символы.ВК,«»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«&»,«&»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«<«,«<»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«>»,«>»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«,»,«</data><data>»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«{«,«<elem><data>»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«}»,«</data></elem>»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«<data><elem>»,«<elem>»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«</elem></data>»,«</elem>»);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«</elem>»,«</elem>» + Символы.ПС);
выхХМЛТело = СтрЗаменить(выхХМЛТело,«</data>»,«</data>» + Символы.ПС);
Возврат выхХМЛТело;
КонецФункции

