v8: Деструктивный анализ формыПопытался сделать полностью виртуальную форму документа
для этого записываю программно все элементы формы и их свойства.
Затем пытаюсь по этому тексту нарисовать форму с "чистого листа".
Проблема в том, что при чтении свойств элемента формы, я не могу никак узнать на какой странице какой панели этот элемент расположен.
В свойствах элемента такой инфы нет.
| | Автор статьи: Последняя редакция №1 от 21.03.08 URL: http://kb.mista.ru/article.php?id=650 | |
Ключевые слова: Форма, копирование, элементы
Собственно идея от TormozIT - он предложил деструктивный анализ для чтения тех свойств элементов, которые нельзя явно получить средствами платформы.
Данная функция строит дерево элементов формы с учетом вложенных панелей (любой уровень вложенности) и учитывает наличие любого количества страниц на них.
Функция ДеструктивныйАнализФормы(МенеджерОбъекта, ИмяФормы) экспорт
ТаблицаДеструктивногоАнализа=Новый ТаблицаЗначений;
ТаблицаДеструктивногоАнализа.Колонки.Добавить("ИмяЭлемента",Новый ОписаниеТипов("Строка"));
ТаблицаДеструктивногоАнализа.Колонки.Добавить("ТипЭлемента");
ТаблицаДеструктивногоАнализа.Колонки.Добавить("Сигнатура",Новый ОписаниеТипов("Строка"));
ТаблицаПанелей=Новый ТаблицаЗначений;
ТаблицаПанелей.Колонки.Добавить("Имя",Новый ОписаниеТипов("Строка"));
ТаблицаПанелей.Колонки.Добавить("ИмяПанели",Новый ОписаниеТипов("Строка"));
ТаблицаПанелей.Колонки.Добавить("Сигнатура",Новый ОписаниеТипов("Строка"));
ТаблицаПанелей.Колонки.Добавить("Сумма",Новый ОписаниеТипов("Число"));
СписокПанелейФормы=Новый СписокЗначений;
ДеревоЭлементовФормы=Новый ДеревоЗначений;
ДеревоЭлементовФормы.Колонки.Добавить("ИмяЭлемента");
ДеревоЭлементовФормы.Колонки.Добавить("ПолноеИмя");
ДеревоЭлементовФормы.Колонки.Добавить("ТипЭлемента");
Корень=ДеревоЭлементовФормы.Строки.Добавить();
Корень.ИмяЭлемента="ЭтаФорма";
Корень.ПолноеИмя="ЭтаФорма";
Корень.ТипЭлемента=Тип("Форма");
тФорма=МенеджерОбъекта.ПолучитьФорму(ИмяФормы);
Для каждого Элем из тФорма.ЭлементыФормы Цикл
тТип=ТипЗнч(Элем);
Если тТип=Тип("Панель") Тогда
СписокПанелейФормы.Добавить(Элем.Имя);
пан=ТаблицаПанелей.Добавить();
пан.Имя=Элем.Имя;
пан.ИмяПанели="";
Для каждого Страница Из Элем.Страницы Цикл
СписокПанелейФормы.Добавить(Элем.Имя+"_"+Страница.Имя,Элем.Имя+"."+Страница.Имя);
пан=ТаблицаПанелей.Добавить();
пан.Имя=Страница.Имя;
пан.ИмяПанели=Элем.Имя;
КонецЦикла;
Иначе
стр=ТаблицаДеструктивногоАнализа.Добавить();
стр.ИмяЭлемента=Элем.Имя;
стр.ТипЭлемента=тТип;
КонецЕсли;
КонецЦикла;
Для каждого пан из СписокПанелейФормы Цикл
ТаблицаДеструктивногоАнализа.Колонки.Добавить(пан.Значение,Новый ОписаниеТипов("Число"));
ТаблицаПанелей.Колонки.Добавить(пан.Значение,Новый ОписаниеТипов("Число"));
КонецЦикла;
Для каждого пан из СписокПанелейФормы Цикл
тФорма=Неопределено;
тФорма=МенеджерОбъекта.ПолучитьФорму(ИмяФормы);
тЭлементыФормы=тФорма.ЭлементыФормы;
тПоз=Найти(пан.Представление,".");
Если тПоз>0 Тогда // это страница панели
тИмяПанели=Лев(пан.Значение,тПоз-1);
тИмяСтраницы=Сред(пан.Значение,тПоз+1);
фПанель=тЭлементыФормы[тИмяПанели];
фСтраница=фПанель.Страницы.Найти(тИмяСтраницы);
Если фСтраница<>неопределено Тогда
фПанель.Страницы.Удалить(фСтраница);
КонецЕсли;
Иначе
тЭлементыФормы.Удалить(тЭлементыФормы[пан.Значение]);
КонецЕсли;
ТаблицаДеструктивногоАнализа.ЗаполнитьЗначения(0,пан.Значение);
ТаблицаПанелей.ЗаполнитьЗначения(0,пан.Значение);
Для каждого Элем из ТаблицаДеструктивногоАнализа Цикл
Попытка
тЭлем=тЭлементыФормы[Элем.ИмяЭлемента];
Исключение
Элем[пан.Значение]=1;
КонецПопытки;
КонецЦикла;
Для каждого Элем из ТаблицаПанелей Цикл
тИмяЭлемента=Элем.Имя;
ЭтоСтраница=Ложь;
Если Элем.ИмяПанели<>"" Тогда // это страница панели
ЭтоСтраница=Истина;
тИмяЭлемента=Элем.ИмяПанели+"_"+Элем.Имя;
Если пан.Значение=Элем.ИмяПанели Тогда
Элем[пан.Значение]=1;
Продолжить;
КонецЕсли;
КонецЕсли;
Если пан.Значение=тИмяЭлемента Тогда
Элем[пан.Значение]=1;
Продолжить;
КонецЕсли;
тПоз=Найти(пан.Представление,".");
Если тПоз>0 Тогда // это страница панели
тИмяПанели=Лев(пан.Значение,тПоз-1);
Если тИмяПанели=Элем.Имя Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если ЭтоСтраница Тогда // это страница панели
Попытка
фПанель=тЭлементыФормы[Элем.ИмяПанели];
фСтраница=фПанель.Страницы.Найти(Элем.Имя);
Исключение
фСтраница=неопределено;
КонецПопытки;
Если фСтраница=неопределено Тогда
Элем[пан.Значение]=1;
КонецЕсли;
Иначе
Попытка
тЭлем=тЭлементыФормы[Элем.Имя];
Исключение
Элем[пан.Значение]=1;
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецЦикла;
колстр=ТаблицаДеструктивногоАнализа.Количество();
Для СчСтр=1 по колстр Цикл
текСтр=ТаблицаДеструктивногоАнализа[колстр-СчСтр];
тСигнатура="";
тСумма=0;
Для каждого пан из СписокПанелейФормы Цикл
тСигнатура=тСигнатура+текСтр[пан.Значение];
тСумма=тСумма+текСтр[пан.Значение];
Конеццикла;
текСтр.Сигнатура=тСигнатура;
Если тСумма=0 Тогда
тЭлемент=Корень.Строки.Добавить();
тЭлемент.ИмяЭлемента=текСтр.ИмяЭлемента;
тЭлемент.ПолноеИмя=текСтр.ИмяЭлемента;
тЭлемент.ТипЭлемента=текСтр.ТипЭлемента;
ТаблицаДеструктивногоАнализа.Удалить(текСтр);
КонецЕсли;
Конеццикла;
Для каждого стр из ТаблицаПанелей Цикл
тСигнатура="";
тСумма=0;
Для каждого пан из СписокПанелейФормы Цикл
тСигнатура=тСигнатура+стр[пан.Значение];
тСумма=тСумма+стр[пан.Значение];
Конеццикла;
стр.Сигнатура=тСигнатура;
стр.Сумма=тСумма;
Конеццикла;
ТаблицаПанелей.Сортировать("Сумма");
Для каждого стр из ТаблицаПанелей Цикл
тДлинаСигнатуры=СтрДлина(стр.Сигнатура);
тСигнатура=стр.Сигнатура;
тСумма=стр.Сумма;
тРодитель=Корень;
Если тСумма>1 Тогда
Для тПоз=1 по тДлинаСигнатуры Цикл
тФлаг=Сред(тСигнатура,тПоз,1);
Если тФлаг="0" Тогда
Продолжить;
КонецЕсли;
тИмяПанелиРодителя=ТаблицаПанелей.Колонки[3+тПоз].Имя;
Если стр.ИмяПанели="" Тогда
тИмяСтроки=стр.Имя;
Иначе
тИмяСтроки=стр.ИмяПанели+"_"+стр.Имя;
КонецЕсли;
Если тИмяСтроки=тИмяПанелиРодителя Тогда
Продолжить;
КонецЕсли;
мРодитель=Корень.Строки.Найти(тИмяПанелиРодителя,"ПолноеИмя",Истина);
Если мРодитель<>неопределено Тогда
Если мРодитель.Уровень()>тРодитель.Уровень() Тогда
тРодитель=мРодитель;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
тПанель=тРодитель.Строки.Добавить();
тПанель.ИмяЭлемента=стр.Имя;
тПанель.ПолноеИмя=стр.Имя;
тПанель.ТипЭлемента=Тип("Панель"); //!!!! добавили панель в дерево
Если стр.ИмяПанели<>"" Тогда
тПанель.ТипЭлемента=Тип("СтраницаПанели");
тПанель.ПолноеИмя=стр.ИмяПанели+"_"+стр.Имя;
КонецЕсли;
КонецЦикла;
Для каждого Элем из ТаблицаДеструктивногоАнализа Цикл
сСигнатура=Элем.Сигнатура;
эПанель=ТаблицаПанелей.Найти(сСигнатура,"Сигнатура");
тРодитель=Корень;
Если эПанель<>неопределено Тогда
ИмяСтрокиДерева=эПанель.Имя;
Если эПанель.ИмяПанели<>"" Тогда
ИмяСтрокиДерева=эПанель.ИмяПанели+"_"+эПанель.Имя;
КонецЕсли;
эСтрока=Корень.Строки.Найти(ИмяСтрокиДерева,"ПолноеИмя",Истина);
Если эСтрока<>неопределено Тогда
тРодитель=эСтрока;
Конецесли;
КонецЕсли;
тЭлемент=тРодитель.Строки.Добавить();
тЭлемент.ИмяЭлемента=Элем.ИмяЭлемента;
тЭлемент.ПолноеИмя=Элем.ИмяЭлемента;
тЭлемент.ТипЭлемента=Элем.ТипЭлемента;
КонецЦикла;
возврат ДеревоЭлементовФормы;
КонецФункции
На данный код вдохновили:
Гений1С
Книга знаний: v8: Копировальщик форм - вложенные формы
и
TormozIT
Книга знаний: v8: Настройка формы по макету
пользуйтесь коллеги.
|