Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

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

Moderator: Moderatoren

juetho
******
Beiträge: 617
Registriert: Di, 20.04.2010 15:46
Wohnort: Berlin

Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

Beitrag von juetho »

Hallo, ich habe in einem Formular ein GridControl mit 4 Spalten und möchte beim Verlassen der Spalten 3 und 4 alle Werte dieser beiden Spalten (Summen über alle Zeilen) prüfen. Je nach Prüfergebnis soll ein Wert in der letzten Zeile geändert oder eine neue Zeile eingefügt werden. Dazu habe ich das Ereignis "Fokusverlust" an die Spalten 3 (fsoll) und 4 (fhaben) gebunden, bekomme aber nicht die gewünschten Werte:

Code: Alles auswählen

Sub details_checkValues(oEvent as Object)
  Dim dSoll as Currency
  Dim dHaben as Currency
  dim oField as Object
  oForm = thisComponent.drawpage.forms.frmDetails
  
  rem bestimme das aktuelle Feld und die derzeitigen Werte
  oField = oEvent.Source.Model  ' Name = "fsoll" oder "fhaben"
  icur = oForm.getRow
  dcurSoll = oForm.getDouble(4)
  dcurHaben = oForm.getDouble(5)
  msgBox( "Feld " + icur + " " + oField.Name + chr(13) + "S " + dcurSoll + " - H " + dcurHaben)
End Sub
Beim Verlassen der Spalte 3 (fsoll) werden die Werte richtig angezeigt. Beim Verlassen der Spalte 4 (fhaben) wird offensichtlich zuerst der Datensatzzeiger geändert und erst dann das Ereignis "Fokusverlust" verarbeitet; deshalb erhalte ich zur Anzeige die geänderte Zeile und deren Werte; ich brauche aber die Zeilennummer und die beiden Werte der soeben verlassenen Zeile. Was kann ich tun?

Folgende Verfahren halte ich für ungeeignet: "Text modifiziert" wegen der ständigen Prüfung bei jedem einzelnen Wert; Drücken oder Loslassen von Maus/Taste wegen der vielen Varianten, wie eine Eingabe in einer Zelle abgeschlossen wird; "Vor Datensatzwechsel" wegen der sofortigen Prüfung von Spalte 3 (fsoll). Ich habe auch versucht, bei Spalte 3 "Fokusverlust" und außerdem "Vor Datensatzwechsel" zu verbinden; aber dann muss ich wegen oEvent.Source beide Routinen trennen und diverse Nebenwirkungen beachten (zumindest wird beim Datensatzwechsel die Prüfung oft auch vorgenommen, wenn nichts geändert wurde).

Hintergrund: Es handelt sich um eine Mini-Buchhaltung. Die Summen von Soll und Haben müssen übereinstimmen; in jeder Zeile gibt es nur entweder Soll oder Haben. Nach Eingabe eines Wertes werden diese Prüfungen vorgenommen. Je nach Prüfungsergebnis wird ein Wert in der aktuellen Zeile auf 0 gesetzt, dazu die Werte in der letzten Zeile geändert oder eine weitere Zeile hinzugefügt.

Danke für Tipps! Jürgen

Nachtrag: Kann und sollte ich ein eigenes Ereignis (Zelle modifiziert oder so) erzeugen? Damit habe ich mich nicht befasst. Ich habe auch nicht verstanden, ob mir die Diskussion Listener für ein Tabellen Kontrollfeld (GridControl) helfen könnte.
Dateianhänge
jt-grid-events.odb
(13 KiB) 154-mal heruntergeladen
Situation: LibO 3.6 auf Win 7 Home Premium (64-bit) mit MySQL (localhost) über JDBC
DPunch
*******
Beiträge: 1112
Registriert: Mo, 02.11.2009 16:16
Wohnort: Marburg

Re: Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

Beitrag von DPunch »

Servus

Nimm entweder das Event "Vor dem Aktualisieren" der Spalte(n)

Code: Alles auswählen

Function details_checkValues(oEvent as Object)
	details_checkValues = True
	oGrid = oEvent.Source.Parent
	icur = oGrid.Parent.Row
	dcurSoll = oGrid.getByIndex(2).CurrentValue
	dcurHaben = oGrid.getByIndex(3).CurrentValue	
	msgBox( "Zeile " + icur + chr(13) + "S " + dcurSoll + " - H " + dcurHaben)
End Function
oder das Event "Vor der Datensatzaktion" des Formulars

Code: Alles auswählen

Function details_checkValues(oEvent as Object)
	details_checkValues = True
	If oEvent.Source.supportsService("com.sun.star.form.FormController") Then
		Exit Function
	Else
		oForm = oEvent.Source
	End If
	icur = oForm.Row
	dcurSoll = oForm.getDouble(4)
	dcurHaben = oForm.getDouble(5)	
	msgBox( "Zeile " + icur + chr(13) + "S " + dcurSoll + " - H " + dcurHaben)
End Function
juetho
******
Beiträge: 617
Registriert: Di, 20.04.2010 15:46
Wohnort: Berlin

Re: Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

Beitrag von juetho »

Hallo, danke für die Tipps. Das Ereignis "Vor dem Aktualisieren" habe ich geprüft; und es klappt im Prinzip. Das Ereignis "Vor der Datensatzaktion" habe ich nicht genauer ausprobiert; ich verstehe noch nicht, unter welchen Umständen oEvent.Source den FormController oder ein Formular liefert.

Inzwischen habe ich mich entschlossen, meine obige Notlösung unter Berücksichtigung deines Codes zu verwenden:
juetho hat geschrieben:Je nach Prüfergebnis soll ein Wert in der letzten Zeile geändert oder eine neue Zeile eingefügt werden...

Ich habe auch versucht, bei Spalte 3 "Fokusverlust" und außerdem "Vor Datensatzwechsel" zu verbinden; aber dann muss ich wegen oEvent.Source beide Routinen trennen und diverse Nebenwirkungen beachten (zumindest wird beim Datensatzwechsel die Prüfung oft auch vorgenommen, wenn nichts geändert wurde).
Bei allen bisherigen Lösungsversuchen tritt folgendes Problem auf: Wenn ich den aktuell eingegebenen Wert zur Prüfung verwende und dann die letzte Zeile bearbeite oder eine neue Zeile einfüge (eigentliche Teilaufgabe), wird zwangsläufig die bisherige Zeile verlassen und der alte Wert zurückgeholt. Natürlich lässt sich auch das regeln; aber alles wird umständlicher. Dann ist eine einfache Lösung besser, auch wenn sie zuerst umständlicher aussieht:
  • Spalte 3 (Soll) benutzt "Beim Fokusverlust" ohne Prüfungen und setzt den Fokus in die nächste passende Zelle; siehe Fokus im GridControl in eine Spalte setzen.
  • Die Berechnungen und Prüfungen werden ausschließlich "Nach dem Datensatzwechsel" (also einem Ereignis des Formulars) vorgenommen.
  • Aber sie werden nur dann ausgeführt, wenn das GridControl den Fokus hat. Dazu frage ich in diesem EventHandler hasFocus beim GridControl ab.
Deine (DPunch) Vorschläge haben mir etwas mehr Verständnis über OO gebracht und helfen mir beim Zugriff auf die Werte. Danke vielmals dafür!

Zusatzfrage: Wieso hast du die EventHandler als Function deklariert? Es gibt doch keine Stelle, wo das Funktionsergebnis ausgewertet werden kann. Für mein Verständnis (von .NET/C#/OOP kommend) kann ein EventHandler nur Sub sein. (Du brauchst es mir nicht ausführlich zu erklären; ein Satz oder ein Link genügt.) Gruß Jürgen
Situation: LibO 3.6 auf Win 7 Home Premium (64-bit) mit MySQL (localhost) über JDBC
DPunch
*******
Beiträge: 1112
Registriert: Mo, 02.11.2009 16:16
Wohnort: Marburg

Re: Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

Beitrag von DPunch »

Servus
juetho hat geschrieben:Zusatzfrage: Wieso hast du die EventHandler als Function deklariert? Es gibt doch keine Stelle, wo das Funktionsergebnis ausgewertet werden kann. Für mein Verständnis (von .NET/C#/OOP kommend) kann ein EventHandler nur Sub sein. (Du brauchst es mir nicht ausführlich zu erklären; ein Satz oder ein Link genügt.) Gruß Jürgen
Diverse Handler bieten die Möglichkeit an, das Event zu "consumen", siehe z.B. OOo API: XKeyHandler. Sowas gibt es allerdings auch im Objekt-orientierten Java.
Unnütze Zusatzinfo:
Die Frage "Function oder Sub" ist bei OOo (mindestens bis 3.2.1) nebensächlich, da eine Sub beliebig als Function benutzt werden kann und vice versa.
juetho
******
Beiträge: 617
Registriert: Di, 20.04.2010 15:46
Wohnort: Berlin

Re: Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

Beitrag von juetho »

DPunch hat geschrieben:Diverse Handler bieten die Möglichkeit an, das Event zu "consumen", siehe z.B. OOo API: XKeyHandler. Sowas gibt es allerdings auch im Objekt-orientierten Java.
In der Tat, das kann sinnvoll sein, auch wenn mir die praktische Umsetzung noch fehlt. Später vielleicht einmal...
Die Frage "Function oder Sub" ist bei OOo (mindestens bis 3.2.1) nebensächlich, da eine Sub beliebig als Function benutzt werden kann und vice versa.
Das kenne ich von C# her auch. Dort wird nur von Methoden mit Rückgabetyp gesprochen - ggf. void. Ich dachte nur, dass Basic-Varianten an dieser Stelle unterscheiden müssen.

Gruß Jürgen
Situation: LibO 3.6 auf Win 7 Home Premium (64-bit) mit MySQL (localhost) über JDBC
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

Beitrag von Karolus »

Hallo
Die Frage "Function oder Sub" ist bei OOo (mindestens bis 3.2.1) nebensächlich, da eine Sub beliebig als Function benutzt werden kann und vice versa.
Das stimmt so nicht ganz, eine 'Function' kann alles was eine 'sub' kann und zusätzlich tatsächlich etwas zurückgeben

Code: Alles auswählen

sub subhallo()
    subhallo = "hallo from sub"
end sub
^^das geht nicht^^

Code: Alles auswählen

function func_hallo()
    func_hallo = "hallo from func"
end function
^^das geht^^

Karolus
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
DPunch
*******
Beiträge: 1112
Registriert: Mo, 02.11.2009 16:16
Wohnort: Marburg

Re: Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

Beitrag von DPunch »

Servus
juetho hat geschrieben:In der Tat, das kann sinnvoll sein, auch wenn mir die praktische Umsetzung noch fehlt. Später vielleicht einmal...
Eine "praktische" Umsetzung sind z.B. KeyPresses, ConfirmDelete im Formular (häng einfach mal eine Function mit Rückgabewert False an das Formularereignes "Löschen bestätigen"), CursorMove etc.
Karolus hat geschrieben:Das stimmt so nicht ganz, eine 'Function' kann alles was eine 'sub' kann und zusätzlich tatsächlich etwas zurückgeben
Da wird die Sub aber gekränkt sein ;)

Code: Alles auswählen

sub subhallo() as String
    subhallo = "hallo from sub"
end sub
Der einzige offensichtliche Unterschied zwischen Function und Sub ist in der Tat, das die Sub mit dem Rückgabewert "Void" vorbelegt ist, die Function hingegen mit "Variant", und dass die Sub den Datentyp Variant auch nicht zurückgeben kann.
Antworten