Seite 1 von 1
Makro ausführen beim selektieren einer Zelle
Verfasst: Fr, 04.02.2011 17:07
von rav156
Hallo zusammen,
ich möchte beim anklicken einer Zelle ein Makro ausführen.
Das habe ich versucht über einen Listener zu realisieren.
Das funktioniert, aber nicht so wie erwartet...
Sobald ich nun in eine Zelle klicke, die sich im Bereich der Spalte M15... befindet, wird der Print-Dialog angezeigt.
Das ist soweit richtig.
Wenn ich nun den Print-Dialog mit OK verlasse, "hängt" die Selektion an den Maus.
So, als würde ich mit gedrückter linker Maustaste die Maus bewegen.
Hat jemand eine Idee, woran das liegt und wie ich dieses Verhalten unterdrücken kann?
Gruß
rav
Hier der Code:
Code: Alles auswählen
Global oListener, oController, oSheet, bomSheet, oRow, oColumn
Dim dlg, dlgBeschreibung As object
Sub AddListener()
oListener = CreateUnoListener("CurCtrl_", "com.sun.star.view.XSelectionChangeListener")
ThisComponent.CurrentController.addSelectionChangeListener (oListener)
End Sub
Sub RemoveListener()
On Error Resume Next
ThisComponent.CurrentController.removeSelectionChangeListener (oListener)
End Sub
Sub CurCtrl_selectionChanged(oEvent)
oDoc = ThisComponent
oController = oDoc.CurrentController
oSheet = oController.activesheet
oZelle = oDoc.getCurrentSelection()
bCheckzelle = HasUnoInterfaces( oZelle, "com.sun.star.table.XCell" )
if bCheckzelle then ' eine einzelne Zelle wurde selektiert
oCelle = oDoc.getCurrentSelection().getCellAddress()
oRow = oCelle.Row
oColumn = oCelle.column
If oColumn = 12 And oRow >= 14 Then 'Spalte M, ab Zeile 15
print "OK"
end if
end if
End Sub
Moderation,4: CODE tags gesetzt
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: Sa, 05.02.2011 02:21
von Stephan
Hat jemand eine Idee, woran das liegt
es liegt ein Programmfehler in OOo vor.
GRuß
Stephan
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: Sa, 05.02.2011 11:18
von rav156
Hallo Stephan,
danke für die Info.
Ich habe gerade mal die Version 3.3.0 installiert. Auch da tritt der Fehler auf.
Der Fehler tritt anscheinend nur auf, wenn ein Dialog geöffnet wird.
Wenn ich nun nach dem Beenden meines Dialogs mit der Maus links klicke, wird
die "hängende" Selektion beendet und es ist die Zelle selektiert, an der sich die Maus gerade befindet.
Kann ich irgentwie einen Mausklick simulieren, damit wäre der Fehler umgangen?
Gruß
rav
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: Sa, 05.02.2011 17:26
von Axel Richter
Hallo,
rav156 hat geschrieben:Der Fehler tritt anscheinend nur auf, wenn ein Dialog geöffnet wird.
Genau, denn einen modalen Dialog in der Ereignisbehandlungsroutine eines Event-Listeners aufzurufen, ist keine gute Idee. Solche Dialoge ziehen die Ereignisbearbeitung vollständig auf sich und das bleibt so, bis der Nutzer den Dialog schließt.
Was genau willst Du mit dem Dialog erreichen? Nur Testausgaben, also er kommt später wieder raus? Dann sorge dafür, dass die Applikation vor Aufruf des Dialogs etwas Zeit für die Abhandlung ihrer EventQueue bekommt. Ein
vor dem Print sollte reichen.
viele Grüße
Axel
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: Sa, 05.02.2011 17:53
von Stephan
rav156 hat geschrieben:Hallo Stephan,
danke für die Info.
Ich habe gerade mal die Version 3.3.0 installiert. Auch da tritt der Fehler auf.
Der Fehler tritt anscheinend nur auf, wenn ein Dialog geöffnet wird.
Wenn ich nun nach dem Beenden meines Dialogs mit der Maus links klicke, wird
die "hängende" Selektion beendet und es ist die Zelle selektiert, an der sich die Maus gerade befindet.
Kann ich irgentwie einen Mausklick simulieren, damit wäre der Fehler umgangen?
Gruß
rav
Meines Wissens tritt dieser FEhler mit dem spezielen Listener bereits seit Jahren auf, thematisiert z.B. hier:
viewtopic.php?f=2&t=988&hilit=Dieser+Co ... ht+korrekt
(damals war ich hier im Forum noch ohne Account)
auch tritt der FEhler, meines Wissens, nicht nur bei Dialogen auf sondern zumindest bei allen Dingen die den Fokus von der selektierten Tabelle weglenken, z.B. auch bei MsgBoxen usw.
Unter dem Link findet sich weitergehend auchh eine Art workaround, der aber insgesamt auchh nicht befriedigt.
Der spezielle Listener ist meines ERachtens bei Mausbedienung nicht zuverlässig, so dasa ich ihn praktisch garnicht einsetze.
Ein Workaround ist wohl mittels eines Mouse-Klick-Listeners denkbar, aber ich habe da konkret aktuell nichts zur Hand und auch keine Erfahrung aus der Praxis (lediglich hatte ich sowas schon einmal aus 'Dritter Hand' gesehen.)
Auch wäre es denkbar auf eine WErtänderung zu reagieren, entweder über einen Listener oder auch über den automatisch über Daten-Gültigkeit zurückgegenen Event-Object-Wert, i.s.:
Code: Alles auswählen
function checkValidity( CellValue as String, CellAddress as String ) as boolean
msgbox( CellValue & " in " & CellAddress)
checkValidity = true
end function
wobei das Ganze ja auch nicht zwingend von der aktuell markierten Zelle ausgehen muss, da ja generell vorher auch eine Zele markiert war, man also auch das Verlassen der letzten ZElle als Ereignis nutzen kann.
Gruß
Stephan
Gruß
Stephan
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: Sa, 05.02.2011 19:14
von Axel Richter
Hallo Stephan,
Stephan hat geschrieben:Der spezielle Listener ist meines Erachtens bei Mausbedienung nicht zuverlässig, so dass ich ihn praktisch gar nicht einsetze.
Also ich setze ihn erfolgreich ein, beispielsweise um mir in bestimmten Tabellen einen Zelleditor-Button zu schaffen, siehe Beispiel.
Man darf nur eben nicht *mitten* in der Ereignisbehandlung von SelectionChange den focus der application auf ein modales Element zwingen, ohne dass vorher Zeit war, die EventQueue zumindest soweit abzuarbeiten, dass alle Listener von dem Ereignis SelectionChange informiert sind. Insbesondere ist es hier wahrscheinlich ein programminterner Listener des betroffeneren Sheets, der für den Abschluss des Selektionsvorganges benötigt wird, welcher noch nicht informiert ist, wenn der modale Dialog startet.
viele Grüße
Axel
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: Sa, 05.02.2011 20:09
von rav156
Hallo Axel,
das "wait" war die Lösung!
Ich selektiere zuerst eine Zelle, auf die der Listerner nicht triggert, dann die kurze Pause und anschließend wird der Dialog geöffnet.
oCell = oSheet.GetCellByPosition(14,oRow)
oController.Select(oCell)
wait 100
print "OK"
So funktioniert es wie gewünscht.
Danke für Eure konstruktive Unterstützung.
Gruß
rav
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: Sa, 05.02.2011 20:49
von Stephan
Also ich setze ihn erfolgreich ein, beispielsweise um mir in bestimmten Tabellen einen Zelleditor-Button zu schaffen, siehe Beispiel.
Deine konkrete Beispieldatei finde ich interessant, weil der Button quasi den Fokus fängt, ich hatte selbst noch garnicht an sowas gedacht.
Gruß
Stephan
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: Sa, 05.02.2011 20:49
von Stephan
das "wait" war die Lösung!
Ich selektiere zuerst eine Zelle, auf die der Listerner nicht triggert, dann die kurze Pause und anschließend wird der Dialog geöffnet.
oCell = oSheet.GetCellByPosition(14,oRow)
oController.Select(oCell)
wait 100
print "OK"
So funktioniert es wie gewünscht.
bei mir funktioniert das nicht (das print kommt immer zweimal), stelle doch bitte eine konkrete Beispieldatei zur Verfügung.
Gruß
Stephan
Re: Makro ausführen beim selektieren einer Zelle
Verfasst: So, 06.02.2011 13:01
von rav156
Hallo Stephan,
vielleicht ist Dein Rechner langsamer und es kfunktioniert mit einer längeren Pause.
Hier der vollständige Code:
Code: Alles auswählen
Global oListener, oController, oSheet, bomSheet, oRow, oColumn
Dim dlg, dlgBeschreibung As object
Sub AddListener()
oListener = CreateUnoListener("CurCtrl_", "com.sun.star.view.XSelectionChangeListener")
ThisComponent.CurrentController.addSelectionChangeListener (oListener)
End Sub
Sub RemoveListener()
On Error Resume Next
ThisComponent.CurrentController.removeSelectionChangeListener (oListener)
End Sub
Sub CurCtrl_selectionChanged(oEvent)
oDoc = ThisComponent
oController = oDoc.CurrentController
oSheet = oController.activesheet
if oSheet.Name <> "Bestellung" then EXIT SUB
oZelle = oDoc.getCurrentSelection()
bCheckzelle = HasUnoInterfaces( oZelle, "com.sun.star.table.XCell" )
if bCheckzelle then ' eine einzelne Zelle wurde selektiert
oCelle = oDoc.getCurrentSelection().getCellAddress()
oRow = oCelle.Row
oColumn = oCelle.column
If oColumn = 12 And oRow >= 14 Then 'Spalte M, ab Zeile 15
oCell = oSheet.GetCellByPosition(14,oRow)
oController.Select(oCell)
wait 100
' LieferantenDialog()
print "OK"
end if
end if
End Sub