When writing user code I sometimes miss a timer service supplied in a similar way as known programming languages do it.
The Basic construct with Wait
is definitely not what I’m looking for.
I would like to know for what reasons no Timer
objkect was implemented.
As usual: it’s a positive action that usually requires a rationale, not its absence It wasn’t implemented because it wasn’t considered needed: in Basic, the other implementations seem to be OK with Wait (I don’t know if this has been changed since then, but at least initially, when StarBasic function set was designed, it was true); and other languages (like Python) have their own means for this
…or BeanShell. I don’t remember where I got this code @ms7777, but judging by the data saved in the spreadsheet, I have never needed it since 2007 - Test Timer Form.ods (16.7 KB)
The following example shows how you can stop the macro thread and restart an arbitrary macro after a certain period of time.
The macro should be placed in the Module1
module of the Standard
spreadsheet document library.
Option VbaSupport 1
Option Explicit
Sub OnTime
Dim rc
rc=Msgbox("Click OK and the next macro will be executed in 30 seconds." & Chr(10) & "Press Cancel To Stop" , MB_OKCANCEL)
If rc=IDOK Then
Application.OnTime Now() + TimeSerial(0,0,30), "Standard.Module1.OnTime" ' Path to this Macro!
End If
End Sub
the terminus »timer service« is a bit vague? does it mean »wait …but without putting the process load on all the time?« as @sokol92 's example?, or do you want accurate measurements of durations for whatever…
Mixed @all:
- There is no actual need for me to use the functionality. As next to always now -and due to age- I’m just interested. My own usage of any software decreased.
- However, I remember that I used timer objects many more years ago when I still wrote some little programs in Delphi or FreePascal/Lazarus.
- I therefore also experimented at some time with a VBA solution similar to what @Soklo92 posted.
- I don’t know that many languages you are knowing. That’s mainly because I could afford to follow my likes and dislikes ()wt6hn2 exceptions) - and I disliked many programming languages (including old Fortran, C/C++, Python, Java, Basic) when I started do investigate them. I only had to accept a bit more contact concerning Fortran in the late 1960es and some dialects of Basic in the 1980es for specific reasons. Now I only accept LibO Basic for purposes of interchange as a kind ofd “lingua franca”.
- My perception of what a timer object should be was formed when I wrote some programs in Delph (1, 2, 7) and for Lazarus.
- There a
Timer
is an object coming with only 3properties
:Name
andTag
as any object, andInterval
as the specific one. It also has 3 typical (first empty)methods
: foronStart
,onStop
, andonTimer
, the third of which is the essential one which needs to be made concrete in a way to make the thing useful at all. - Essential is also that the object, when automatically initialized, is connected to an interrupt by the hardware as driven by the OS system which reads in turn the Interval from the timer. and, of course, that it doesn’t block different code running or interfere with it without explicit measures.
- That “positive” reasons exist should not need a special proof here. The fact that serious systems have timers in the described sense for long now, and the fact that the functionality is aked for now and then, should suffice. Just one example from today: Apache OpenOffice Community Forum - Macro that saves and closes an AOO if no activity is detected for 10 minutes - (View topic).
- So I feel justified my question for a “negative” reason: Not concerning Basic, but the API.
Unfortunately, my example doesn’t work for macros that are in the application library.
We can implement a timer using the RefreshPeriod property and a listener that handles the refresh event. However, to do this we will have to open the auxiliary (hidden) document.
If necessary, I can create an example (but not today).
Your link talks about closing the LO after a certain period of inactivity. At the same time, we can discuss closing BasicIDE (if necessary).
I think you can do a link to the same file, to avoid the use of a second file. It works without macros.
@sokol92: Thanks for your explanitions, and generally for sharing your insight.
As already told I see currently no need by myself. The linked request was by a user of AOO 4.1.14 (on a Mac) where surly no sufficient VBA support is available.
I did not check what the ScriptForge team has to offer. My question aimed exclusively at the LibO API.
I do not mind.
If the macros are in the document, then the mechanism described in my message above works (based on emulation in LO of the Application.OnTime method).
If the macros are in the application library, then we will need the auxiliary document (this can be created on the fly).
Consideration at the level of conjecture. If we see Update every in the user interface, then somewhere in the API there really is the ability to start a timer, isn’t it?
Of course there is. The question is how to get closer to it…
Objection.
I read API
as shorthand for ApplicationProgrammingInterface
and would expext its “services” to be available to somebody programming something for the application.
That this isn’t a well regarded concept stands behind my general “mild criticism”. And sometimes I get a sore throat when I have to use that “second API” with its .uno: commands because the corresponding services are not available via the API.
Of course there is. The question is how to get closer to it
with google »libreoffice sdk timer«
https://api.libreoffice.org/docs/cpp/ref/a00606.html
with google »libreoffice sdk timer«
I simply am not capable of this idea.
OMG! 16 years ago!
I never used the timer since then, either …
OMG! 16 years ago!
I used that code in a simple test spreadsheet too - just to make sure this thing would work. Yes, it worked then, it continues to work today. No updates. No version changes. Do you feel how much cooler you are than Microsoft? Thank you
Hope this will help… Timer Function
Option Explicit
REM ***** BASIC *****
Global oDoc As Object
Global oController As Object
Global oSheets As Object
Global ArraySheets() As Variant
Global ArrayData(0, 0) As Variant
Sub SetGlobalVar
oDoc = ThisComponent
oController = oDoc.getCurrentController()
oSheets = oDoc.getSheets()
End Sub
Sub SetDataWithArray
If (isnull (oDoc)) Then
Call SetGlobalVar
End If
Erase ArrayData()
Dim StartTime As Double
Dim SecondsElapsed As Double
StartTime = Timer
Dim iRowCount As Long
Dim iColCount As Long
REM Number of rows
iRowCount = 10000
REM Number of columns
iColCount = 100
Redim ArrayData(iRowCount - 1, iColCount - 1 )
REM Call ScreenSetFreeze
Dim oAce1 As Boolean
REM the current value of Automatic calculation
oAce1 = oDoc.isAutomaticCalculationEnabled()
oDoc.lockControllers() REM no screen actualization
oDoc.addActionLock() REM turn off the Autocalculate
Dim i As Long
Dim j As Long
For i = 0 to iRowCount - 1
For j = 0 to iColCount - 1
ArrayData(i, j) = "test" & Cstr(( i + 1 )*( j + 1 ))
Next
Next
Dim ActiveSheetName As String
Dim oSheetName As String
Dim oSheet As Object
ActiveSheetName = oDoc.getCurrentController().getActiveSheet().Name
oSheetName = ActiveSheetName
oSheet = oSheets.getByName( oSheetName )
Dim iRowTarge As Long
Dim iColTarge As Long
iRowTarge = 0
iColTarge = 0
Dim oCellRange As Object
oCellRange = oSheet.getCellRangeByPosition( iColTarge, iRowTarge, iColTarge + iColCount - 1, iRowTarge + iRowCount - 1)
oCellRange.setDataArray(ArrayData)
Dim M As Integer, N As Integer, P As Integer
M = 1024 : N = 2048 : P = M + N
Dim Cell As Object
oDoc.Sheets(0).getCellRangeByName("A1001").Value = P
P = N/M
oDoc.Sheets(0).getCellRangeByName("A1002").setValue(P)
REM Call ScreenUnsetFreeze
oDoc.removeActionLock() REM enable Autocalculate
oDoc.unlockControllers() REM enable screen rendering
oDoc.enableAutomaticCalculation(oAce1) REM primal set of Autocalculate
REM Measure elapsed time (seconds)
SecondsElapsed = Timer - StartTime
Msgbox("Processing time: " & SecondsElapsed & "seconds")
REM Without ScreenSetFreeze, 1000 x 100 = 1 second
REM With ScreenSetFreeze, 1000 x 100 = 1 second
End Sub REM SetDataWithArray