Ereignisbehandlung

In einer Vorherigen Mail bat ich um Hilfe bei der Realisierung einer Ereignisbehandlung in LO Calc. Ich musste lernen, dass es so, wie ich es damals dachte nichts werden würde.
Wolfgang empfahl mir es mit UNO zu probieren. Das hab ich gemacht und eine Lösung gefunden, siehe BASIC-Code am Ende der Mail.
Ich habe gelernt, dass die von LO angebotenen Ereignisse ausschließlich das Dokument betreffen. UNO bietet da noch eine ganze Reihe weiterer Ereignismöglichkeiten, die von LO bisher nicht weiter umgesetzt wurden.

Gruß von Henning

Hier der Code:

REM ***** BASIC *****

option Explicit

'######################################################################

Sub Init()

  'Dieses Init() muss einmal beim Öffnen des Dokuments durchlaufen
  'werden. Es richtet die erforderlichen Listener für die
  'Ereignisauslösung ein.
  'Für einen automatischen Durchlaf von Init() beim Programmstart
  'ist dieses Makro Init() dem Ereignis 'Dokument öffnen' zuzuordnen.
  
  Dim i as Integer
  
  'Blatt auf dem Zellen sind, die bei Inhaltsänderungen ein
  'Ereignis auslösen sollen
  Dim oSheet As Object
  'Bereich der Zellen, in dem eine Inhaltsänderung zur Auslösung
  'eines Ereignisses führen soll
  Dim ColLeft, RowTop, ColRight, RowBottom
  Dim oCellRange As Object
  
  'Für jedes Blatt in der Mappe den gewünschten Listener erzeugen
  'Ein Zellenbereich (Range-Object) ist an das jeweilige Blatt gebunden.
  For i=0 to thisComponent.Sheets.count-1
    'Verweis auf Blatt i
      oSheet = ThisComponent.Sheets(i)
      'Verweis auf den Zellenbereich für den das Modify-Ereignis gesetzt
      'werden soll
    ColLeft = 3
    RowTop = 3
    ColRight = 3
    RowBottom = oSheet.Rows.Count-1
    oCellRange = oSheet.GetCellRangeByPosition(ColLeft,RowTop,ColRight,RowBottom)
    'Für den Zellenbereich einen Listener erzeugen
    AddListener(oCellRange)
  Next i
  
End Sub 'Init()

'######################################################################

'Listener für den angegebenen Bereich erzeugen.

Sub AddListener(Range As Object)

  'Prefixname
  Const sPrefix = "Sheet_"
  'ListenerInterfaceName
  Const sListenerName = "com.sun.star.util.XModifyListener"
  
  'Einen Listener erzeugen
  Dim oListener As Object
  oListener = createUnoListener(sPrefix,sListenerName)
  
  'Den Listener dem Sender, hier Zellenbereich, zuordnen (registrieren)
  Range.addModifyListener(oListener)

End Sub 'AddListener(..)

'======================================================================

'Einsprungziel, wenn der Listener eine Änderung feststellt.

Sub Sheet_modified(Source As EventObject)
  InhaltGeaendert
End Sub 'Sheet_modified(..)

'======================================================================

'Alle Listener entsorgen

Public Sub Sheet_disposing(Source As EventObject)
  ' ? Keine Ahnung was hier zu tun ist.
  ' Ist hier überhaupt etwas zu tun?
  MsgBox "Scheet_disposing(..)"
  MsgBox Broadcaster.Dbg_Properties
End Sub 'Sheet_disposing(..)

'======================================================================

'Die Listener entfernen.

Public Sub RemoveListener(Range as Object)
  ' ?.removeModifyListener(oListener)
  ' Für ? müsste der Sender, in diesem Projekt der Zeilenbereich
  ' (siehe AddListener(..) oben) eingesetzt werden.
  ' Dazu ist das Range-Objekt als globale Variable zu definieren.
  ' Oder gibt es eine andere Möglichkeit an das Sende-Objekt zu
  ' zu gelangen?
End Sub 'RemoveListener(..)

'######################################################################

Public Sub InhaltGeaendert()

  Dim s As String

  'Verweis auf die aktuelle Zelle
  Dim oCellAddress As Object
  oCellAddress = ThisComponent.CurrentSelection.CellAddress
  
  'Verweis auf das Blatt mit der geänderten Zelle
  Dim oSheet As Object
  oSheet = ThisComponent.Sheets(oCellAddress.Sheet)
  
  'Zeile mit der geänderten Zelle
  Dim iRow as Integer
  iRow = oCellAddress.Row
  
  'Spalte mit der geänderten Zelle
  Dim iCol As Integer
  iCol = oCellAddress.Column
  
  'Verweis auf die geänderte Zelle
  Dim oCell As Object
  oCell = oSheet.getCellByPosition(iCol,iRow)
  
  'Inhalt der geänderten Zelle als Variant
  Dim v As Variant
  v = oCell.String
  
  s = "InhaltGeändert()"
  s = s & chr(13)
  s = s & "Sheet=" & oSheet.Name
  s = s & chr(13)
  s = s & "Row=" & iRow & ", Col=" & iCol
  s = s & chr(13)
  s = s & "Value=" & v
  
  MsgBox s
  
End Sub 'InhaltGeaendert(..)

'######################################################################