Calc - Document getEvents vs Sheet getEvents

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!

Except by the order in properties, I see the same arrays for the two methods, except of course, the different names for different events that support each object.

Hello,

Cannot be specific on first part of question as it deals much deeper into the internals than I am familiar with. However, just having or missing an ImplementationName doesn’t seem to be related to objects.

As for the second part, those are properties. The sequence has no relevance. Reverse the sequence and you will get the same result. If you have 50 properties there is no sequence. That is what name is for - to determine what the value is attached to.

Hmm, hadn’t experimented, just assumed since the property names were the same, the element order mattered. Guess it could “look” and see that the one with a .Name value of “Script” had to be the one holding the routine.

Am very much liking working with these events via the keyboard rather than the GUI…