Hi, all,
Am curious why, in a Calc macro, a document’s getEvents method does not appear to return an object, whereas a sheet’s getEvents method does, even though what a document returns looks and acts like an object.
Assuming:
- sSheet is the name of a sheet in the document, with iSheet being its index
- oDoc = ThisComponent
- oSheet = oDoc.getSheets().getByName(sSheet) ( or .getByIndex(iSheet) if working off indexes )
- oEvents = oDoc.getEvents (or oSheet.getEvents) gives you info on events for that object, but not the actual events.
To get the available event names we use
- aEvents = oDoc.getElementNames (or oSheet.getElementNames)
which returns a string array populated with the events available to the object (“onFocus”, “mousePressed”, etc.).
After getting the available event names, use index i from aEvents to get the details on a particular event (there is no getByIndex method for getting events out of an object):
- oEvent = oEvents.getByName(aEvents(i))
which returns a variant associated with the event in question, that is either empty, indicating there is no routine associated to that event, or a two-element array descriptor (shown below).
Running xRay on oDoc.getEvents returns an object of type “( no name )”, while running it on oSheet.getEvents returns a sheet object ( “ScSheetEventsObj” ).
There are a few differences between the two - no ImplementationName property for oDoc (obviously, as it’s “no name”), no disposing method for oSheet, etc., but they share many methods, include getByName, getElementNames, hasByName, replaceByName, and so on.
For not having a name, oDoc.getEvents sure seems to return an object.
So far as the descriptor array, also curious why the array elements for events in oDoc are reversed from what oSheet uses. This is a two-element array of type com.sun.star.beans.PropertyValue (or just make it yourself with a custom type declaration) which controls what routine is associated with a particular event.
’ Define the type
Type tEventDescriptor
.Name As String
.Handle As Long
.Value As Variant
.State As Long
End Type
The .Value property of one of the elements shows the routine to be associated with the event. For a module using Basic as the scripting language, assuming the routine was in Module1, it would be:
’ Create variables for the two array elements
Dim vEventAboutDescriptor As tEventDescriptor
Dim tEventRoutineDescriptor As tEventDescriptor
’ Populate the variables
With tEventAboutDescriptor
.Name = “EventType”
.Handle = -1
.Value = “Script”
.State = 0
End With
With tEventRoutineDescriptor
.Name = “Script”
.Handle = -1
.Value = “vnd.sun.star.script:Standard.Module.<YOUR_ROUTINE_NAME_HERE>?language=Basic&location=document”
.State = 0
End With
’ Create the descriptor arrays
Dim aDocEventsDescriptor(1) As tEventDescriptor
Dim aSheetEventsDescriptor(1) As tEventDescriptor
’ A Document descriptor:
aDocEventsDescriptor(0) = tEventAboutDescriptor
aDocEventsDescriptor(1) = tEventRoutineDescriptor
’ A Sheet descriptor:
aSheetEventsDescriptor(0) = tEventRoutineDescriptor
aSheetEventsDescriptor(1) = tEventAboutDescriptor
To set or clear an event:
- oEvents.replaceByName(sEvent, aDocEventsDescriptor) (for a document)
- oEvents.replaceByName(sEvent, aSheetEventsDescriptor) (for a sheet)
with sEvent being the name from the list in .getElementNames
Set .Value in the appropriate element of the descriptor to a routine in your module as shown above to set an event, or an empty string to clear the event.
So, does anyone know why a document’s getEvents method doesn’t appear to return an object as does a sheet’s getEvents method does, and why the event descriptor array elements are reversed between a document and a sheet?
Thanks!