There is no timer service. Why?

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.

:slight_smile: As usual: it’s a positive action that usually requires a rationale, not its absence :wink: 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 :slight_smile:

…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)

2 Likes

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 3 properties: Name and Tag as any object, and Interval as the specific one. It also has 3 typical (first empty) methods: for onStart, onStop, and onTimer, 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… :slightly_smiling_face:

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.

with google »libreoffice sdk timer«
https://api.libreoffice.org/docs/cpp/ref/a00606.html

1 Like

I simply am not capable of this idea.

OMG! 16 years ago!
I never used the timer since then, either …

1 Like

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 :smiley:

1 Like

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