|
v7: Программное определение секций таблицы | ☑ | ||
---|---|---|---|---|
0
MadDAD
23.05.18
✎
09:53
|
Надо кому?
Есть решение с использованием DynWrapperX |
|||
1
MadDAD
23.05.18
✎
09:53
|
Вернее не определение а получение списка
|
|||
2
MadDAD
23.05.18
✎
10:07
|
Перем ScrptCtrl;
Процедура ПатчBlang() //Пропатчим blang по методике Chessman'а для передачи объектов 1C в DynWrapper ТекстМодуля = " |Public Const PAGE_EXECUTE_READWRITE = &h40 | |Public Wrap |Set Wrap = CreateObject(""DynamicWrapperX"") |Wrap.Register ""Kernel32"", ""LoadLibrary"" , ""i=s"", ""r=h"" |Wrap.Register ""Kernel32"", ""GetProcAddress"" , ""i=hs"", ""r=u"" |Wrap.Register ""Kernel32"", ""VirtualProtect"" , ""i=lllp"", ""r=l"" |Wrap.Register ""Kernel32"", ""HeapAlloc"", ""i=lll"", ""r=l"" |Wrap.Register ""Kernel32"", ""GetProcessHeap"", ""r=l"" |Wrap.Register ""Kernel32"", ""HeapFree"", ""i=lll"",""r=l"" |'.................................................................... | |Class DWX_Blang | Private ptr | Private hHeap | Private buf | | Private Sub Class_Initialize | handle = Wrap.LoadLibrary(""blang"") | Addr = Wrap.GetProcAddress(handle, ""?CallAsFunc@CStdOleBLContext@@UAEHHAAVCValue@@PAPAV2@@Z"") | Offset = &h3A9 | ptr = Addr + Offset | | hHeap = Wrap.GetProcessHeap() | buf = Wrap.HeapAlloc(hHeap, 0, 4) | | Wrap_Blang() | End Sub | | Private Sub Class_Terminate | Wrap.HeapFree hHeap, 0, buf | End Sub | | Private Sub Wrap_Blang() | If Wrap.NumGet(ptr, 0, ""t"") = &h458D Then | Exit Sub | End If | Wrap.VirtualProtect ptr, &h21, PAGE_EXECUTE_READWRITE, buf | | Wrap.NumPut &h458D , ptr, 0, ""t"" 'LEA EAX,DWORD PTR SS:[EBP-40] | Wrap.NumPut &hC0 , ptr, 2, ""b"" ' | Wrap.NumPut &h0E8B , ptr, 3, ""t"" 'MOV ECX,DWORD PTR DS:[ESI] | Wrap.NumPut &h498B , ptr, 5, ""t"" 'MOV ECX,DWORD PTR DS:[ECX+48] | Wrap.NumPut &h48 , ptr, 7, ""b"" ' | Wrap.NumPut &h00C7 , ptr, 8, ""t"" 'MOV DWORD PTR DS:[EAX],3 | Wrap.NumPut &h3 , ptr, 10, ""u"" | Wrap.NumPut &h4889 , ptr, 14, ""t"" 'MOV DWORD PTR DS:[EAX+8],ECX | Wrap.NumPut &h08 , ptr, 16, ""b"" ' | Wrap.NumPut &h458D , ptr, 17, ""t"" 'LEA EAX,DWORD PTR SS:[EBP-2C] | Wrap.NumPut &hD4 , ptr, 19, ""b"" ' | Wrap.NumPut &h00C7 , ptr, 20, ""t"" 'MOV DWORD PTR DS:[EAX],3 | Wrap.NumPut &h3 , ptr, 22, ""u"" | Wrap.NumPut &h4889 , ptr, 26, ""t"" 'MOV DWORD PTR DS:[EAX+8],ECX | Wrap.NumPut &h08 , ptr, 28, ""b"" ' | Wrap.NumPut &hE9 , ptr, 29, ""b"" 'JMP 21011F3F | Wrap.NumPut &h03C4 , ptr, 30, ""u"" ' | | '....................Убираем за собой.................... | Wrap.VirtualProtect ptr, &h21, Wrap.NumGet(buf), buf | End Sub |End Class | |Set Blang = New DWX_Blang |"; ScrptCtrl = СоздатьОбъект("MSScriptControl.ScriptControl"); ScrptCtrl.Language = "vbscript"; ScrptCtrl.TimeOut = -1; ScrptCtrl.AddCode(ТекстМодуля); КонецПроцедуры //-------------------------------------------------------------------------------------------------------------------------------- Функция ПрочитатьСекцию(Указатель, НомерСекции, Таб) СекцияУказатель = DWX.NumGet(Указатель, 4) + НомерСекции * 20; Секция = СоздатьОбъект("СписокЗначений"); Секция.Установить("Имя", DWX.StrGet(DWX.NumGet(СекцияУказатель,16),"s")); Секция.Установить("Начало",DWX.NumGet(СекцияУказатель, 4) +1); Секция.Установить("Конец", DWX.NumGet(СекцияУказатель, 8)+1); Секция.Установить("Уровень",DWX.NumGet(СекцияУказатель, 12)); Возврат Секция; КонецФункции //-------------------------------------------------------------------------------------------------------------------------------- Процедура ПолучитьСекции(Таб) ПатчBlang(); Лист = DWX.numGet(DWX.ObjPtr(Таб), 56); // [0x38h] CSheet* ВертикальныеСекцииУказатель = Лист + 480; // [0x1E0h] &CSheet->VLayout ГоризонтальныеСекцииУказатель= Лист + 460; // [0x1CCh] &CSheet->HLayout ГоризонтальныхыхСекций = DWX.NumGet(ГоризонтальныеСекцииУказатель, 8, "u"); // &CSheet->HLayout->Num ВертикальныхСекций = DWX.NumGet(ВертикальныеСекцииУказатель, 8, "u"); // &CSheet->VLayout->Num Для Счетчик = 0 По ГоризонтальныхыхСекций - 1 Цикл Секция = ПрочитатьСекцию(ГоризонтальныеСекцииУказатель, Счетчик, Таб); ГоризонтальныеСекции.ДобавитьЗначение(Секция, Секция.Получить("Имя")); КонецЦикла; Для Счетчик = 0 По ВертикальныхСекций - 1 Цикл Секция = ПрочитатьСекцию(ВертикальныеСекцииУказатель, Счетчик, Таб); ВертикальныеСекции.ДобавитьЗначение(Секция, Секция.Получить("Имя")); КонецЦикла; КонецПроцедуры |
|||
3
trdm
23.05.18
✎
10:18
|
Ваше кунфу - божественно!
|
|||
4
Ёпрст
23.05.18
✎
12:18
|
(0) а.. применение то какое ? К чему это ?
|
|||
5
MadDAD
23.05.18
✎
13:09
|
(4) На самом деле это кусок класса-наследника таблицы. Возникла задача выяснить поместится ли секция на страницу. При выборе исходной таблицы получаю все секции и рассчитываю их высоты в твипах. Можно было бы не париться получением секций, но так уж получилось, что я раньше немного ковырял моксели и знал где что брать.
В качестве применения можно например в универсальной обработки печати документов выяснить есть ли в таблице секция "Подписи" к примеру или "Логотип" и если есть - вывести. А если нет - не выводить. |
|||
6
Злопчинский
23.05.18
✎
18:40
|
(5) > "Возникла задача выяснить поместится ли секция на страницу"
- ну выведи секцию в черновик - если после вывода стало таб.КоличествоСтраниц() больше - значит не поместилась... |
|||
7
Злопчинский
23.05.18
✎
18:42
|
ты лучше сюда посмотри https://www.forum.mista.ru/topic.php?id=818192&all=1 - 98 топик, второй врпрос
|
|||
8
MadDAD
24.05.18
✎
10:42
|
(6) Некрасиво :) для каждой таблицы держать еще и черновик, а так посчитал высоту таблицы в твипах с учетом масштабирования, посчитал высоту секции, посчитал количество листов и остаток на текущем листе и оценил.
Ну и штатный КоличествоСтраниц() - тормозной метод. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |