eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
 
Offline
Пол: 
Сообщений: 382
|
Знатоки, подскажите, как отобразить/скрыть строку состояния в Calc программно. Sub DisplayStatusBar(state As Boolean) Dim document As Object Dim dispatcher As Object
document = ThisComponent.CurrentController.Frame dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
Dim args1(0) As New com.sun.star.beans.PropertyValue args1(0).Name = "StatusBarVisible" args1(0).Value = state
dispatcher.executeDispatch(document, ".uno:StatusBarVisible", "", 0, args1()) End Sub
Код выше работоспособен, но мне кажется громоздким. Вообще, можно писать короче, работая с объектной моделью, а не через диспетчер? Как тогда? И как вывести туда свою информацию? В Excel есть два свойства: Application.DisplayStatusBar [Boolean] Application.StatusBar [Variant]
|
|
« Последнее редактирование: 20 Июнь 2020, 21:06 от eeigor »
|
Записан
|
|
|
|
sokol92
|
Описано здесь. Пример использования: ' Сопоставляет время вызова "родной" функции Basic и функции, вызванной через FunctionAccess Sub TestFunctionAccessSpeed Dim n as Long ' число вызовов функции Dim i as Long ' счетчик вызовов Dim oIndicator ' индикатор статуса Dim oFA ' FunctionAccess Dim j as Long, s as String, t as Long, d as Double, fm as String, title as String
n=500000 fm="#,##0" oFA = createUnoService( "com.sun.star.sheet.FunctionAccess" ) oIndicator=ThisComponent.getCurrentController().frame.createStatusIndicator() ' создаем индикатор статуса oIndicator.start("Сравнение скорости вызова функций", n) ' стартуем индикатор статуса s="Число вызовов функций: " & format(n, fm) For j=1 To 2 title=IIf(j=1, "Вызов Basic SIN", "Вызов FunctionAccess SIN") oIndicator.setText(title) oIndicator.setValue(0) t=GetSystemTicks() For i=1 to n If i mod 50000=0 Then oIndicator.setvalue(i) End If If j=1 Then d=sin(i) Else d=oFA.callFunction("SIN", Array(CDbl(i))) End If Next i s=s & Chr(10) & title & ". Время: " & Format(GetSystemTicks-t, fm) Next j oIndicator.end() ' закрываем индикатор статуса Msgbox s End Sub
|
|
« Последнее редактирование: 21 Июнь 2020, 15:15 от sokol92 »
|
Записан
|
Владимир.
|
|
|
sokol92
|
Дополнил свой ответ.
|
|
|
Записан
|
Владимир.
|
|
|
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
 
Offline
Пол: 
Сообщений: 382
|
Ubuntu Linux 18.04 LTS LibreOffice Calc 6.4.4.2.
sokol92, очень интересное решение. Правда, я спрашивал про StatusBar, но хотел использовать эту панель именно с этой целью: вывести импровизированную строку состояния из символов псевдографики. Но вы угадали мою конечную цель: построить ProgressBar. Задал значения переменных: n = 5000; m = 500.
Как удалить индикатор? Скриншот с неудалённым индикатором.
Другой вопрос, чуть не по теме. Как обновить экран? В Excel для этих целей использовал оператор DoEvents в цикле. А так, ScreenUpdating [Boolean]. Здесь что-то подобное ScreenUpdating False|True: ThisComponent.lockControllers ThisComponent.unlockControllers
|
|
« Последнее редактирование: 21 Июнь 2020, 19:31 от eeigor »
|
Записан
|
|
|
|
sokol92
|
"Индикатор" и есть аналог StatusBar, но с расширенными возможностями. Он состоит из двух частей, которыми можно управлять независимо: текста и "прогрессбара".
Если макрос завершается аварийно, то индикатор остается (я не знаю пока, как с этим воевать). При нормальном завершении индикатор удаляется после того, как будет выполнен метод end и обнулен счетчик ссылок на индикатор (как и другие объекты).
С обновлением экрана, надеюсь, помогут более опытные коллеги.
|
|
|
Записан
|
Владимир.
|
|
|
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
 
Offline
Пол: 
Сообщений: 382
|
Я, в своё время работал с Microsoft Access, и там сделано подобным образом. https://docs.microsoft.com/en-us/office/vba/access/concepts/miscellaneous/use-the-status-bar-progress-meteracSysCmdRemoveMeter Remove progress meter Но всё равно это находка. Спасибо В отношении метода end() в описании сказано: The instance must be gone by using ref count or disposing. (Экземпляр должен быть удален с помощью...). Почему "должен быть"? Кто это должен сделать и как? При нормальном завершении индикатор удаляется после того, как будет выполнен метод end Сомневаюсь, однако... UPDНу, вот, и ответ. Вы использовали все методы, кроме одного: oIndicator.reset() Он и доделает остальное. reset() Clear progress value and description
|
|
« Последнее редактирование: 21 Июнь 2020, 21:15 от eeigor »
|
Записан
|
|
|
|
rami
|
Если макрос завершается аварийно, то индикатор остается (я не знаю пока, как с этим воевать). Просто нужно выполнить код: Sub Main ThisComponent.CurrentController.StatusIndicator.end() End Sub Ну, вот, и ответ. Вы использовали все методы, кроме одного: Код: oIndicator.reset() Он и доделает остальное. reset() Clear progress value and description reset() только сбрасывает значения, но не завершает.
|
|
|
Записан
|
|
|
|
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
 
Offline
Пол: 
Сообщений: 382
|
Он состоит из двух частей, которыми можно управлять независимо: текста и "прогрессбара" На этом форуме, вроде, этой информации нет. Я не нашёл. Есть реализацию через форму ( https://forumooo.ru/index.php/topic,3774.0.html). А это очень полезный инструмент.
|
|
|
Записан
|
|
|
|
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
 
Offline
Пол: 
Сообщений: 382
|
reset() только сбрасывает значения, но не завершает Да нет же. Вот так: oIndicator.end() ' закрываем индикатор статуса oIndicator.reset() ' clear all После этого в строке состояния появляется системное сообщение: Лист 1 из 1 Что и требовалось.
|
|
« Последнее редактирование: 21 Июнь 2020, 21:26 от eeigor »
|
Записан
|
|
|
|
rami
|
Я взял макрос из Ответ #1, закомментировал строку кода oIndicator.end() ' закрываем индикатор статуса, статус индикатор остался незавершённый, затем выполнил предложенный мною макрос и статус индикатор убрался полностью из строки состояния.
|
|
|
Записан
|
|
|
|
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
 
Offline
Пол: 
Сообщений: 382
|
Оформлять в виде отдельной процедуры не обязательно, можно прямо здесь: oIndicator = ThisComponent.getCurrentController().frame.createStatusIndicator() ' oIndicator.end() ' закрываем индикатор статуса ThisComponent.CurrentController.StatusIndicator.end() Работает так же, как и с oIndicator.reset() Вообще, не очевидная модель объектов: ThisComponent.CurrentController().frame.createStatusIndicator() ThisComponent.CurrentController.StatusIndicator.end() Как будто: ThisComponent.CurrentController().frame.createStatusIndicator() Is Not ThisComponent.CurrentController.StatusIndicator Проверил с помощью Xray: в обоих случаях это объект com.sun.star.task.XStatusIndicatorА работает по-разному. Вот так нормально и понятно (не люблю я эти геттеры и сеттеры): ' oIndicator = ThisComponent.getCurrentController().frame.createStatusIndicator() ' создаем индикатор статуса oIndicator = ThisComponent.CurrentController().StatusIndicator() Работает. Зачем нужно было обращение к frame ?
|
|
« Последнее редактирование: 22 Июнь 2020, 00:05 от eeigor »
|
Записан
|
|
|
|
sokol92
|
Rami, большое спасибо!
|
|
|
Записан
|
Владимир.
|
|
|
sokol92
|
В версии LO 6.4 появился Infobar, который, в частности, также можно использовать для целей, указанных в данной теме. Пример из #1 расширен: ' Сопоставляет время вызова "родной" функции Basic и функции, вызванной через FunctionAccess Sub TestFunctionAccessSpeed Dim n as Long ' число вызовов функции Dim i as Long ' счетчик вызовов Dim oController ' контроллер документа Dim oIndicator ' индикатор статуса Dim oFA ' FunctionAccess Dim j as Long, s as String, t as Long, d as Double, fm as String, title as String, bRed as Boolean
n=200000 fm="#,##0" oFA = createUnoService( "com.sun.star.sheet.FunctionAccess" ) oController=ThisComponent.getCurrentController() oIndicator=oController.StatusIndicator() ' создаем индикатор статуса oController.appendInfobar("MyInfobar", "Выполняется макрос", "Дождитесь завершения работы макроса, иначе можно получить непредсказуемый результат", 3, Array(), True) oIndicator.start("Сравнение скорости вызова функций", n) ' стартуем индикатор статуса s="Число вызовов функций: " & format(n, fm) bRed=True For j=1 To 2 title=IIf(j=1, "Вызов Basic SIN", "Вызов FunctionAccess SIN") oIndicator.setText(title) oIndicator.setValue(0) t=GetSystemTicks() For i=1 to n If i mod 20000=0 Then oIndicator.setvalue(i) If bRed And j=2 And i/n>=0.7 then oController.updateInfobar("MyInfobar", "Макрос скоро завершится", "Дождитесь завершения работы макроса, иначе можно получить непредсказуемый результат", 2) bRed=False End If End If If j=1 Then d=sin(i) Else d=oFA.callFunction("SIN", Array(CDbl(i))) End If Next i s=s & Chr(10) & title & ". Время: " & Format(GetSystemTicks-t, fm) Next J oIndicator.end() ' закрывам индикатор статуса oController.removeInfobar("MyInfobar") ' закрываем инфобар Msgbox s End Sub
|
|
|
Записан
|
Владимир.
|
|
|
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
 
Offline
Пол: 
Сообщений: 382
|
Хороший пример. Берём на вооружение.
|
|
|
Записан
|
|
|
|
|