Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

Antwort erstellen


BBCode ist eingeschaltet
[img] ist ausgeschaltet
[url] ist eingeschaltet
Smileys sind ausgeschaltet

Die letzten Beiträge des Themas
   

Ansicht erweitern Die letzten Beiträge des Themas: Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

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

von DPunch » Do, 06.12.2012 18:56

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.

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

von Karolus » Do, 06.12.2012 08:42

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

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

von juetho » Do, 06.12.2012 08:40

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

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

von DPunch » Mi, 05.12.2012 22:10

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.

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

von juetho » Di, 06.11.2012 11:04

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

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

von DPunch » So, 04.11.2012 14:57

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

Base: GridControl mit Fokusverlust bei 2 Zellen prüfen

von juetho » So, 04.11.2012 13:49

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) 155-mal heruntergeladen

Nach oben