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