OO 4.0 LO 4.1.0.4- CurrentController.select

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

moritz
*****
Beiträge: 216
Registriert: Mi, 20.10.2004 20:54

OO 4.0 LO 4.1.0.4- CurrentController.select

Beitrag von moritz »

Hallo,
seit dem Update auf LibreOffice von 4.0 auf 4.1.0.4 funktioniert eines meiner Makros nicht mehr. OpenOffice 4.0 zeigt das gleiche Verhalten.
Ich habe eine Calc- Tabelle, in die fortlaufend in eine Spalte Zahlen eingetippt werden. Einige Zellen sind gesperrt. Hier soll der Cursor automatisch auf die nächste ungesperrte Zelle springen. Das funktioniert bei mir seit der ersten öffentlichen OO- Version gut. In der Version Lo 3.5 unter Opensuse habe ich noch den Vergleich.
Das ganze wird über einen SelectionChangeListener gesteuert.
Wird in der aktiven Selection eine gesperrte Zelle festgestellt, wird der Curosr mit
ThisComponent.CurrentController.select(oZelle) um eine Zeile nach unten oder oben verrschoben. Die Änderung löst ein neues Event aus. Das Problem im aktuellen OO und Lo scheint zu sein, dass diese Änderung nicht aktualisiert wird und ThisComponent.getcurrentselection() noch die gesperrte Zelle auswählt. Damit hängt das Programm in einer Schleife, was zum Absturz von Lo führt.
Hat jemand einen Tip zur Umgehung dieses Problems? Da es in beiden neuen Programmversionen auftritt, wird es wohl kein Bug sein.
Vielen Dank für eure Hilfe
Moritz


Dieser wird eingeschalten:
Sub Ein_SelectionChangeListener
DialogLibraries.LoadLibrary("Standard")
Dim oDoc As object
Dim oSheet As object
oDocView = ThisComponent.getCurrentController
oListener = CreateUnoListener( "MeineTabelle_", "com.sun.star.view.XSelectionChangeListener" )
oDocView.addSelectionChangeListener(oListener)
oDoc = Stardesktop.CurrentComponent
oSheet = oDoc.CurrentController.ActiveSheet
End Sub 'Ein_SelectionChangeListener

Das ist das eigentliche Programm:
Sub MeineTabelle_selectionChanged(oEvent)
Dim oCurr as object
Dim oZelle As object
oDoc = Stardesktop.CurrentComponent
oSheet = oDoc.CurrentController.ActiveSheet
if oSheet.Name = "MeineTabelle" then
on error goto schluss
oCurr = ThisComponent.getcurrentselection()
If oCurr.CellProtection.IsLocked = true Then
If letzteAktiveZelle.Row < oCurr.CellAddress.Row then
oZelle =oSheet.getCellByPosition(oCurr.CellAddress.Column,oCurr.CellAddress.Row+1)
ThisComponent.CurrentController.select(oZelle) 'Hier wird die aktive Zelle eine Zeile nach unten verschoben
else
If letzteAktiveZelle.Row > oCurr.CellAddress.Row then
oZelle =oSheet.getCellByPosition(oCurr.CellAddress.Column,oCurr.CellAddress.Row-1)
ThisComponent.CurrentController.select(oZelle) 'Hier wird die aktive Zelle eine Zeile nach oben verschoben
end if
End If '
end if
letzteAktiveZelle = oCurr.CellAddress
else
call Aus_SelectionChangeListener
end if
exit sub
schluss:
call Aus_SelectionChangeListener
End Sub '
F3K Total
********
Beiträge: 3723
Registriert: Mo, 28.02.2011 17:49

Re: OO 4.0 LO 4.1.0.4- CurrentController.select

Beitrag von F3K Total »

Hallo Moritz,
werde aus deinem Unterfangen nicht schlau.
Ein Hinweis, es gibt inzwischen Tabellenereignisse (Rechtsklick auf Tabellenreiter), unter Anderem "Auswahl geändert".
Gruß R
moritz
*****
Beiträge: 216
Registriert: Mi, 20.10.2004 20:54

SOLVED Re: OO 4.0 LO 4.1.0.4- CurrentController.select

Beitrag von moritz »

Hallo R
vielen Dank für Deine Hilfestellung. Ich habe jetzt das Makro mit dem Tabellen- Ereignis "Auswahl geändert" wie von dir vorgeschlagen verknüpft. Das Ergebnis ist das gleiche, hat miich aber auf den Lösungsweg gebracht. In den älteren OO- Versionen wurde offensichtlich bei dem von einem Ereignis ausgelöstem Makro das Makro schrittweise abgearbeitet und dabei kein neues Ereignis ausgelöst. Jetzt wird das Makro erneut aufgerufen, wenn das Makro eine Auswahl ändert. (was im Grunde genommen auch logisch ist)

Hier das abgespeckte Testprogramm mit Deiner Lösung. Muss also bei den Ereignissen des Tabellenblattes eingetragen werden.

[code]Sub Test_selectionChanged(oCurr)
Dim oCurrentSelection As Object
Dim oZelle As object
Dim oDoc As Object
Dim oSheet As object
If oCurr.SupportsService ("com.sun.star.sheet.SheetCell") then
oCurr = oEvent
oDoc = Stardesktop.CurrentComponent
oSheet = oDoc.CurrentController.ActiveSheet
If oCurr.CellProtection.IsLocked = true Then
oZelle =oSheet.getCellByPosition(oCurr.CellAddress.Column,oCurr.CellAddress.Row+2)
'Hier muss der Event- Handler ausgeschaltet werden
ThisComponent.CurrentController.select(oZelle)
'Hier muss der Event- Handler eingeschaltet werden
End If
End If
End Sub
[/code]

Leider kann ich in dieserr Variante das Makro von dem Ereignis nicht trennen, bzw. den Listener nicht ausschalten.
In meiner Variante würde das so funktionieren

[code]Sub Aus_SelectionChangeListener
oDocView.removeSelectionChangeListener(oListener)
End Sub 'Aus_SelectionChangeListener[/code]


Die funktionierende Lösung ist damit unter den aktuellen OO und LO- Varianten so:
Leider verlangsamt das Ein- und Ausschalten des Listeners das Programm etwas:

[code]
Sub MeineTabelle_selectionChanged(oEvent)
Dim oCurr as object
Dim oZelle As object
oDoc = Stardesktop.CurrentComponent
oSheet = oDoc.CurrentController.ActiveSheet
if oSheet.Name = "MeineTabelle" then
on error goto schluss
oCurr = ThisComponent.getcurrentselection()
If oCurr.CellProtection.IsLocked = true Then
If letzteAktiveZelle.Row < oCurr.CellAddress.Row then
oZelle =oSheet.getCellByPosition(oCurr.CellAddress.Column,oCurr.CellAddress.Row+1)
call Aus_SelectionChangeListener
ThisComponent.CurrentController.select(oZelle) 'Hier wird die aktive Zelle eine Zeile nach unten verschoben
call Ein_SelectionChangeListener
else
If letzteAktiveZelle.Row > oCurr.CellAddress.Row then
oZelle =oSheet.getCellByPosition(oCurr.CellAddress.Column,oCurr.CellAddress.Row-1)
call Aus_SelectionChangeListener
ThisComponent.CurrentController.select(oZelle) 'Hier wird die aktive Zelle eine Zeile nach oben verschoben
call Ein_SelectionChangeListener
end if
End If '
end if
letzteAktiveZelle = oCurr.CellAddress
else
call Aus_SelectionChangeListener
end if
exit sub
schluss:
call Aus_SelectionChangeListener
End Sub '
[/code]

Vielen Dank
Moritz
F3K Total
********
Beiträge: 3723
Registriert: Mo, 28.02.2011 17:49

Re: OO 4.0 LO 4.1.0.4- CurrentController.select

Beitrag von F3K Total »

Bei mir passiert da nix ...???
Was willst du eigentlich erreichen?
Kannst Du ein Beispieldokument hochladen?
Gruß R
moritz
*****
Beiträge: 216
Registriert: Mi, 20.10.2004 20:54

Re: OO 4.0 LO 4.1.0.4- CurrentController.select

Beitrag von moritz »

Hallo R
ich habe eine Tabelle, in die in eine Spalte von oben nach unten manuell Zahlen eingetragen werden. Der Cursor ist so eingestellt, dass er beim Druck auf die Entertaste eine Zeile nach unten springt. Einige Zellen sind gesperrt. Diese Zellen sollen vom Cursor übersprungen werden, so dass die Zahlen ohne auf den Bildschirm zu sehen fortlaufend eingegeben werden können.
Bei der Sache handelt es sich um einen Preisspiegel, wie ihn die Architekten anlegen. Meist bekommt man die Daten als Datei. Da werden sie automatisch in die Calc- Tabelle eingelesen. Manchmal muss man es aber mit der Hand machen und da ist das Makro eine große Hilfe.
Als Anlage sende ich dir das Prinzip der Tabelle.
Viele Grüße
Moritz
Dateianhänge
Test für gesperrte Zellen und Listener.ods
(9.09 KiB) 180-mal heruntergeladen
F3K Total
********
Beiträge: 3723
Registriert: Mo, 28.02.2011 17:49

Re: OO 4.0 LO 4.1.0.4- CurrentController.select

Beitrag von F3K Total »

Da sind keine Makros drinne???
Gruß R
moritz
*****
Beiträge: 216
Registriert: Mi, 20.10.2004 20:54

Re: OO 4.0 LO 4.1.0.4- CurrentController.select

Beitrag von moritz »

Nein, Makros sind in der Tabelle nicht enthalten.
Sie sind ausschließlich unter MeineMakros in LO bzw. AOO gespeichert.
Der Listener muss natürlich aktiviert werden, siehe mein erstes Schreiben.
Oder der Aufruf des Makros ist wie von dir empfohlen an das Tabellen- Ereignis gekoppelt. Das geht aber nur, wenn die Vorübergehende Abschaltung möglich ist.

Sub Ein_SelectionChangeListener
DialogLibraries.LoadLibrary("Standard")
Dim oDoc As object
Dim oSheet As object
oDocView = ThisComponent.getCurrentController
oListener = CreateUnoListener( "MeineTabelle_", "com.sun.star.view.XSelectionChangeListener" )
oDocView.addSelectionChangeListener(oListener)
oDoc = Stardesktop.CurrentComponent
oSheet = oDoc.CurrentController.ActiveSheet
End Sub


Viele Grüße
Moritz
Antworten