Aloha
Jason hat geschrieben:Da mein Code aber selbst auch etwas in eine überwachte Zelle schreiben soll, ist es unerlässlich den ModifyListener davor zu beenden, weil er sich sonst selbst wieder aufruft.
Dafür muss man den Listener nicht unbedingt beenden, das lässt sich auch mit einer Hilfsvariable umsetzen.
Jason hat geschrieben:Da mein Makro universell einsetzbar sein soll, weis ich vorher nicht, für wie viele Tabellen ich einen XModifyListener öffnen muss.
Es reicht ein einziger Listener, der auf mehrere Zellbereiche angesetzt wird.
Der Listener bietet seine Funktionalität so oder so, ob nun einer oder mehrere - es kommt nur darauf an, dass der betroffene Zellbereich überhaupt weiss, dass er einen Listener benachrichtigen soll und welchen.
Als globale Variablen musst Du also die Referenz auf den Listener sowie auf die mit einem Listener versehenen Zellbereiche haben.
Jason hat geschrieben:aber wie definiert man ein unbestimmtes Array? Wenn ich ein bestimmtes globales Array versuche mit redim zu ergänzen, so scheinen alle neuen Einträge des Arrays nicht als Global zu gelten und werden dem entsprechend nicht gespeichert.
Ein Redim erzeugt ein neues leeres Array mit der neuen Dimension.
Was Du benötigen würdest, wäre ein "ReDim
Preserve", welches bewirkt, dass die alten Inhalte / Referenzen des Arrays erhalten bleiben.
Jason hat geschrieben:und ich hab wirklich eine Stunde gesucht -, welche Funktionen, bzw. Events der "com.sun.star.util.XModifyListener"
Eine Google-Suche mit dem Suchbegriff "com.sun.star.util.XModifyListener" spuckt direkt als erstes einen Verweis auf die
API aus, in der die Methoden (in diesem Fall nur die Methode) zu finden ist

Dort sieht man, dass das Interface die Methode "modified" zur Verfügung stellt.
Zusätzlich erbt das XModifyListener-Interface noch (wie alle Listener) vom
com.sun.star.lang.XEventListener die Methode "disposing".
Für einen Einsteiger sicher nicht wirklich überschaubar, aber für die Zukunft möglicherweise ja irgendwann gut, das mal gehört zu haben.
Fazit: Dein Listener muss also die Methoden "disposing" und "modified" bereithalten.
Damit haben wir eigentlich alles, was Du benötigst:
-Du musst dem Listener die Methoden "disposing" und "modified" zur Verfügung stellen
-Du musst die Referenz auf den Listener global hinterlegen
-Du musst die Zellbereiche global hinterlegen, vornehmlich in einem Array
Schau mal, ob Du mit dem Beispielcode hier was anfangen kannst:
Code: Alles auswählen
Global myModLis as Object REM Der Listener
Global myCellArray(0) as Object REM Globales Array für die betroffenen Zellbereiche
Global bManuallyCalled as Boolean REM Hilfsvariable, damit man den Listener nicht durch seine eigenen Änderungen aufruft
Global bListenerAlreadyAdded as Boolean REM Um zu verhindern, dass der Listener möglicherweise mehrmals gestartet wird
Private Const sCellRange as String = "A1:A10" REM Zellbereich, der überwacht werden soll
Private Const sLookupTable as String = "Lookup" REM Tabelle, in der nach möglichen Vorschlägen gesucht werden soll
Private Const nSearchColumn as Integer = 3 REM In welcher Spalte soll in der Tabelle nach dem Begriff gesucht werden
Private Const nStartRow as Integer = 8 REM Ab wecher Zeile gibt es Ergebnisse?
Private Const nEndRow as Integer = 41 REM Bis zu welcher Zeile?
Sub AddMyListener
bManuallyCalled = False
If bListenerAlreadyAdded Then Exit Sub
oDoc = thisComponent
nSheetCount = oDoc.Sheets.Count-1
ReDim myCellArray(nSheetCount) as Object
myModLis = CreateUnoListener( "MyListener_", "com.sun.star.util.XModifyListener" )
For x = 0 To nSheetCount
oSheet = oDoc.Sheets(x)
myCellArray(x) = oSheet.getCellRangeByName(sCellRange)
myCellArray(x).addModifyListener(myModLis)
Next x
bListenerAlreadyAdded = True
MsgBox "ModifyListener gestartet für Bereich " & sCellRange & " in allen Tabellen"
End Sub
Sub AutoComplete(Cell as Object)
If NOT Cell.supportsService("com.sun.star.sheet.SheetCell") Then Exit Sub REM Mehrere Zellen markiert
oSheet = thisComponent.Sheets.getByName(sLookupTable)
oSD = oSheet.createSearchDescriptor
sSearch = Cell.String
With oSD
.SearchString = "^" & sSearch
.SearchRegularExpression = True
End With
oSearchArea = oSheet.getCellRangeByPosition(nSearchColumn,nStartRow,nSearchColumn,nEndRow)
oResult = oSearchArea.findAll(oSD)
If isNull(oResult) Then REM Kein Ergebnis
MsgBox("Der Zauber konnte nicht gefunden werden. Eine Eigenkreation?")
Exit Sub
End If
If oResult.Count > 1 Then REM Mehrere Ergebnisse, nicht unbedingt zusammenhängend
MsgBox("Sorry, aber das reicht nicht. Der Zaubername muss genauer angegeben werd.")
Exit Sub
End If
nRow = oResult.RangeAddresses(0).StartRow
If nRow <> oResult.RangeAddresses(0).EndRow Then REM Mehrere Ergebnisse, die direkt aufeinanderfolgen in der Lookup-Tabelle
MsgBox("Sorry, aber das reicht nicht. Der Zaubername muss genauer angegeben werd.")
Exit Sub
End If
nCol = oResult.RangeAddresses(0).StartColumn
sNewString = oSheet.getCellByPosition(nCol,nRow).String
If MsgBox("Zauber" & Chr(13) & sNewString & Chr(13) & "gefunden, soll der Rest ergänzt werden?", 3, "Jason's Frage:") = 6 Then
bManuallyCalled = True
Cell.String = sNewString
End If
End Sub
Sub MyListener_disposing(oEvent)
End Sub
Sub MyListener_modified(oEvent)
If bManuallyCalled Then
bManuallyCalled = False
Exit Sub
End If
AutoComplete(thisComponent.CurrentSelection(0))
End Sub
Sub RemoveMyListener
If isNull(myModLis) Then Exit Sub
oDoc = thisComponent
nSheetCount = oDoc.Sheets.Count-1
For x = 0 To nSheetCount
myCellArray(x).removeModifyListener(myModLis)
Next x
bListenerAlreadyAdded = False
MsgBox "ModifyListener aus allen Tabellen entfernt"
End Sub
Bei Fragen dazu einfach nochmal melden.