Возможно ли создать многостраничную форму в LO Base

Автор Kadet, 25 ноября 2019, 21:58

0 Пользователи и 1 гость просматривают эту тему.

Kadet

Цитата: rami от 11 декабря 2019, 17:22Если msgbox не вызывается, то макроось не назначался или что-то не срослось. К двум указанным макросам добавьте макрос DemoCalc из документа DEMO4 что я выложил раньше.
Проанализировал этот момент и понял следующее. Дело в том, что в той Демке у вас назначение макросов происходит следующим образом:
AddButton(7, oRow, "RED", "/", 400, RGB(0,0,0), "DemoCalc")
AddButton(7, oRow+1, "COPY", "//", 400, RGB(0,0,0), "ButtonPushEvent")
AddButton(8, oRow, "DEL", "X", 400, RGB(255,0,0), "ButtonPushEvent")
AddButton(8, oRow+1, "GOT", "готов", 1300, RGB(0,0,255), "ButtonPushEvent")

Т.е. вы тут подменяете исполнительный макрос по нажатию именно той самой процедурой "ButtonPushEvent"
Sub ButtonPushEvent(ev as com.sun.star.awt.ActionEvent)
msgbox ev.Source.Model.Name
msgbox ev.ActionCommand 'получаем значение ActionCommand
End Sub

Т.е., получается, что макросы вообще не нужно передавать, а везде прошить эту "ButtonPushEvent", а уже в ней, методом исследования ev.ActionCommand определять какая кнопка нажата, в каком листе, в каком документе и всё пр. По кнопке "RED", "/" событие ActionCommand всё равно не происходит.
Ведь теперь я этот макрос, которые Вы помогли мне отредактировать, использую во всех формах, листах и документах базы... один для всего.
Мне кажется это путь к усложнению и повышению длительности работы программы... излишней замороченности.
Проще ли это? Или я чего-то не пойму.

Kadet

Поразмыслив немного понял Вашу логику. Вы предлагаете подменить все передаваемые на кнопки макросы одним промежуточным и уже в нём, по уникальным Name, Tag или ActionCommand определять какой макрос выполнять и с какими входными параметрами.
В принципе... а в чём упрощение, если при передаче макросов напрямую, без промежуточной процедуры, по сути получается тоже самое - расшифровка входных параметров и исполнение нужного макросы?

rami

Цитата: Kadet от 11 декабря 2019, 21:39Вы предлагаете подменить все передаваемые на кнопки макросы одним промежуточным и уже в нём, по уникальным Name, Tag или ActionCommand определять какой макрос выполнять и с какими входными параметрами.
У вас есть четыре типа кнопок для каждого блока данных, для каждого типа можно сделать свой макрос, а можно всем назначить один промежуточный — это как вам удобно, я на этот счёт ничего не предлагал, а только "сэкономил макросы", вместо четырёх назначил один.

Kadet

#78
Да, я в итоге въехал во всю систему. Однако типов кнопок у меня гораздо больше. Это только в одном списке заявок их 4, а ещё в самих заявках их по 5-10 типов. И в других документах по несколько собственных типов. И везде я теперь использую один макрос создания кнопки. Так что унифицировать, к сожалению это дело не получается.

Однако, всё же что-то пошло не так. Не могу вытащить значение, занесённое в ActionCommand.
Заношу так:
oDoc.CurrentController.getControl(oButtonModel).setActionCommand(oRow)
Достаю так:
oRow = oEvent.ActionCommand
Результат oRow=0.


rami

Мой пример у вас работает? Покажите ваш код создания кнопок (чтобы можно было запустить).

Kadet

Цитата: rami от 12 декабря 2019, 10:14Мой пример у вас работает?
Ваш пример у меня работает. Макрос создания кнопки - тот самый, который отредакрировали Вы, только доработанный и расширенный.
Sub AddButton(oDoc, oSheet, oCol%, oRow%, nam$, label$, sTag$, iWidth%, iHeight%, oKegl%, color&, macro$)
Dim vCell, oDrawPage, oControlShape, oButtonModel, sScriptURL$, oForm
Dim aSize As new com.sun.star.awt.Size
Dim aEvent As new com.sun.star.script.ScriptEventDescriptor

oDrawPage = oSheet.DrawPage

oControlShape = oDoc.createInstance("com.sun.star.drawing.ControlShape")
vCell = oSheet.getCellByPosition(oCol, oRow)
oControlShape.setPosition(vCell.Position)
aSize.Width = iWidth
aSize.Height = iHeight
oControlShape.setSize(aSize)

oButtonModel = CreateUnoService("com.sun.star.form.component.CommandButton")
oButtonModel.Label = label
oButtonModel.FontStyleName = "Полужирный"
oButtonModel.FontWeight = 150
oButtonModel.FontHeight = oKegl
oButtonModel.TextColor = color
oButtonModel.VerticalAlign = com.sun.star.style.VerticalAlignment.MIDDLE
oButtonModel.Name = nam
oButtonModel.Printable = False
oButtonModel.Tag = sTag

oControlShape.setControl(oButtonModel)
    oDrawPage.add(oControlShape)

oDoc.CurrentController.getControl(oButtonModel).setActionCommand(oRow)
' oDoc.CurrentController.getControl(oButtonModel).setActionCommand("ActionCommand: " & oRow)

sScriptURL = "vnd.sun.star.script:DBLibrary." & macro & "?language=Basic&location=application"
oForm = oDrawPage.getForms().getByIndex(0)
With aEvent
.AddListenerParam = ""
.EventMethod = "actionPerformed"
.ListenerType = "XActionListener"
.ScriptCode = sScriptURL
.ScriptType = "Script"
End With
oForm.registerScriptEvent(oForm.Count-1, aEvent)

oControlShape.Anchor = vCell
oControlShape.MoveProtect = True
oDoc.CurrentController.setFormDesignMode(false)
End Sub

Свойство ActionCommand у переменной oEvent появляется, но оно всегда пустое.

rami

Поясните эту строку:
Цитата: Kadet от 12 декабря 2019, 10:20sScriptURL = "vnd.sun.star.script:DBLibrary." & macro & "?language=Basic&location=application"
DBLibrary — библиотека, macro — макрос, а где модуль в котором содержится этот макрос?

Kadet

Цитата: rami от 12 декабря 2019, 10:40Поясните эту строку:
Поясняю:
AddButton(oDoc, oSheet, 8, i, oRowSetZK.getInt(1), "/", i, 400, 400, 8, RGB(0,0,0), "OpenForm.ZAKMETOpenForm")
Так как макрос создания кнопки универсальный, а нужные макросы находят в разных модулях, то я завожу в переменную macro "Модуль.Макрос"

Kadet

Однако, строка:
oDoc.CurrentController.getControl(oButtonModel).setActionCommand(oRow)
Оказалась крайне нестабильной. Я этот макрос не окружал обходчиком ошибок. И он начал мне выкидывать ошибки в самых непонятных моментах. Закрываешь форму - выбрасывает ошибку на этой строке. Прерываю недоформированную таблицу тоже выкидывает ошибку. Пришлось эту строку зарэмить.


Kadet

Наконец-то попал на неё:
Ошибка времени выполнения Basic.
Вызвано исключение
Type: com.sun.star.container.NoSuchElementException
Message: .

Kadet

Однако, проявляется беда с этой заморозкой и разморозкой документа calc.
Использую везде вот такой набор команд:
'Заморозка экрана
oDoc.lockControllers()
oDoc.addActionLock()
'Сброс заморозки
oDoc.removeActionLock()
oDoc.unlockControllers()

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

Чаще всего это происходит тогда, когда одна процедура формирования страницы ещё не завершилась, а запускается уже другая процедура формирования другой страницы. Такие случаи происходят постоянно. Я, вроде бы по возможности постарался обойти эти переключения, но запретить их вовсе нельзя, ибо для работы это будет ещё хуже, а вот обойти всё это грамотно не получается.

Воспроизвести это в демо-доке не получается. В демке всё работает нормально. А вот в базе, во встроенном calc какая-то беда.

Причём, иной раз производит чистку страницы и тогда заполняемая таблица просто остаётся пустой. При этом кнопки всё равно формируются, вне зависимости от заморозки. Происходит такая картинка как во вложении.
А иной раз экран просто не очищается. А "пустота" с кнопками начинает заполняться прямо поверх ранее заполненной таблицы и в этом случает кнопки не соответствуют заказам, поверх которых они выставлены.

В общем заморочки, какой-то с этими заморозками.

Kadet

Сам разобрался. Изучил матчасть. В описании методов значится следующее:
void addActionLock() - увеличивает количество блокировок объекта на единицу.
void removeActionLock() - уменьшает количество блокировок объекта на единицу.
логический isActionLocked() - Возвращает TRUE если хотя бы один замок существует.

Я то полагал, что removeActionLock вообще сбрасывает все блокировки, а он только уменьшает уровень на единицу. Значит у меня получаются ситуации, когда блокировок больше единицы.
Сделал следующую процедурку:
Do
oDoc.removeActionLock()
Loop While oDoc.isActionLocked()

Kadet

Сделал. Стало лучше. Однако иногда всё же проскакивает неразмороженное заполнение.

Kadet

Вот так:
'Сброс заморозки страницы
Do While oDoc.isActionLocked()
oDoc.removeActionLock()
oDoc.unlockControllers()
Loop

Вроде бы получилось. Пока не выбрасывало.