Makro ausführen beim selektieren einer Zelle

Das Tabellenkalkulationsprogramm

Moderator: Moderatoren

rav156
Beiträge: 5
Registriert: Sa, 12.12.2009 12:15

Makro ausführen beim selektieren einer Zelle

Beitrag 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
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Makro ausführen beim selektieren einer Zelle

Beitrag von Stephan »

Hat jemand eine Idee, woran das liegt
es liegt ein Programmfehler in OOo vor.



GRuß
Stephan
rav156
Beiträge: 5
Registriert: Sa, 12.12.2009 12:15

Re: Makro ausführen beim selektieren einer Zelle

Beitrag 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
Axel Richter
****
Beiträge: 159
Registriert: So, 17.10.2010 16:54

Re: Makro ausführen beim selektieren einer Zelle

Beitrag 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

Code: Alles auswählen

wait 500
vor dem Print sollte reichen.

viele Grüße

Axel
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Makro ausführen beim selektieren einer Zelle

Beitrag 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
Axel Richter
****
Beiträge: 159
Registriert: So, 17.10.2010 16:54

Re: Makro ausführen beim selektieren einer Zelle

Beitrag 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
Dateianhänge
SelectionChange.ods
(9.3 KiB) 250-mal heruntergeladen
rav156
Beiträge: 5
Registriert: Sa, 12.12.2009 12:15

Re: Makro ausführen beim selektieren einer Zelle

Beitrag 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
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Makro ausführen beim selektieren einer Zelle

Beitrag 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
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Makro ausführen beim selektieren einer Zelle

Beitrag 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
rav156
Beiträge: 5
Registriert: Sa, 12.12.2009 12:15

Re: Makro ausführen beim selektieren einer Zelle

Beitrag 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

Antworten