Seite 1 von 1

Eingabekontrolle in Formularen - Bennung fehlender Felder

Verfasst: So, 16.02.2014 20:46
von RobertG
Hallo *,

bei der Eingabe in Formulare gibt es bisher zwei mögliche Fehlermeldungen bei fehlenden Eingaben: Zum einen meldet sich die grafische Benutzeroberfläche, wenn für ein Feld eine Eingabe nötig war - allerdings mit einer Allroundmeldung. Ist das Ganze nicht in der Benutzeroberfĺäche des Formulars angegeben, dann kommt eine Meldung der zugrundeliegenden Datenbank, natürlich mit einem SQL-Auszug.
Die deutschsprachige Meldung bekomme ich zur Zeit hier gar nicht reproduziert.
Ich wollte eine Möglichkeit erstellen, mit der die Meldung klar mitteilt, bei welchen Feldern noch eine Eingabe erforderlich ist. Wie üblich habe ich mir erst einmal etwas zusammengestrickt, was sicher noch besser läuft. Hier erst einmal der Code, den wir eventuell noch gemeinsam verbessern können:

Code: Alles auswählen

SUB Eingabekontrolle(oEvent AS OBJECT)
	REM Dieses Makro sollte an die folgenden Ereignisse des Formulars gebunden werden: 'Vor der Datensatzaktion'
	REM Jedes Eingabefeld muss mit einem Beschriftungsfeld verbunden sein. Im Tabellenkontrollfeld ist dies über die Spaltenbeschriftung geregelt.
	REM Die Beschriftungen der Felder werden benannt, bei denen ein Eintrag fehlt.
	REM Ob das Feld tatsächlich einen Inhalt hat lässt sich nicht ohne Probleme ermitteln. Checkboxen und Radiobutttons speichern Statuswerte,
	REM Zahlenfelder sgeben als Wert '0' aus, wenn sie leer sind ...
	DIM Inputfeld()
	DIM inAnzahl AS INTEGER
	DIM oDocCtl AS OBJECT
	DIM stText AS STRING
	DIM oForm AS OBJECT
	IF InStr(oEvent.Source.ImplementationName,"ODatabaseForm") THEN
		oForm = oEvent.Source
		oDocCtl = oForm.Parent.Parent.CurrentController
		stText = ""
		inAnzahl = 0
		Inputfeld = array("NumericField","ListBox","CheckBox","TextField","DateField","TimeField","CurrencyField","FormattedControl","ComboBox","RadioButton", "PatternField", "GridControl")
		REM Die Überprüfung von CheckBox und RadioButton ist eigntlich sinnlos. Sollen sie immer einen Wert abspeichern, so ist die Eingabe immer gleich
		FOR i=0 TO UBound(oForm.ControlModels())
			FOR k = 0 TO UBound(Inputfeld())
				IF InStr(oForm.ControlModels(i).DefaultControl,Inputfeld(k)) > 0 THEN
					IF (InStr(oForm.ControlModels(i).DefaultControl,"GridControl") > 0) THEN
						FOR n = 0 TO oForm.ControlModels(i).Count() - 1
							IF oForm.ControlModels(i).getByIndex(n).InputRequired = True AND IsEmpty(oForm.ControlModels(i).getByIndex(n).CurrentValue) THEN
								IF stText = "" THEN 
									stText = oForm.ControlModels(i).getByIndex(n).Label
								ELSE				
									stText = stText + ", " + oForm.ControlModels(i).getByIndex(n).Label
								END IF
								inAnzahl = inAnzahl + 1
							END IF
						NEXT
					ELSE
						IF oForm.ControlModels(i).InputRequired = True THEN
							IF (InStr(oForm.ControlModels(i).DefaultControl,"CheckBox") > 0) OR (InStr(oForm.ControlModels(i).DefaultControl,"RadioButton") > 0) THEN	
								IF (oDocCtl.getControl(oForm.ControlModels(i)).peer.State = 0) THEN			
									IF stText = "" THEN
										stText = oForm.ControlModels(i).Label
									ELSE				
										stText = stText + ", " + oForm.ControlModels(i).Label
									END IF
									inAnzahl = inAnzahl +1
								END IF
							ELSEIF (InStr(oForm.ControlModels(i).DefaultControl,"ListBox")) THEN
								IF (oDocCtl.getControl(oForm.ControlModels(i)).peer.selectedItem = "") THEN
									IF stText = "" THEN
										stText = oForm.ControlModels(i).LabelControl.Label
									ELSE				
										stText = stText + ", " + oForm.ControlModels(i).LabelControl.Label
									END IF
									inAnzahl = inAnzahl +1
								END IF
							ELSEIF  (oDocCtl.getControl(oForm.ControlModels(i)).peer.Text = "") THEN
								IF stText = "" THEN
									stText = oForm.ControlModels(i).LabelControl.Label
								ELSE				
									stText = stText + ", " + oForm.ControlModels(i).LabelControl.Label
								END IF
								inAnzahl = inAnzahl +1
							ELSE
							END IF
						END IF
					END IF
				END IF
			NEXT
		NEXT
		IF inAnzahl > 0 THEN	
			IF inAnzahl = 1 THEN
				msgbox "Im Feld "+stText+" ist ein Eintrag erforderlich."
			ELSE
				msgbox "In den Feldern "+stText+" sind Einträge erforderlich."
			END IF
			oForm.cancelRowUpdates
		END IF
	END IF
END SUB
Vom Prinzip her sollte dieses Makro alle Felder des Formulars automatisch überprüfen. Ist bei einem Feld "Eingabe erforderlich" auf "Ja" gesetzt und wird kein Inhalt eingegeben, so sollte eine Meldung erfolgen und die Eingabe unterbrochen werden.

Gruß

Robert

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: So, 23.02.2014 11:15
von RobertG
Grundsätzlich gibt Base nur Meldungen für fehlende Einträge aus, wenn sowohl in der Tabelle der Datenbank als auch in den Formularen steht, dass ein Eintrag benötigt wird. Dabei wird immer der Datenbankname eines Feldes ausgegeben. Fehlen mehrere Einträge, so erfolgt nach der ersten Eingabe erneut der Hinweis auf eben das nächste Feld. Fehlt im Formular "Eintrag erforderlich → Ja", so wird gar keine Meldung ausgegeben und der Datensatz einfach nicht abgespeichert. Der Cursor bleibt beim Bewegen mit dem Tabulator einfach hängen.
Mache ich nur Einträge im Formular (Eintrag erforderlich → Ja), so wird dies durch Base völlig ignoriert.
Die Eingabekontrolle ist in LO 4.2 zur Zeit völlig daneben. Es wird keine Meldung mehr ausgegeben, dass irgendwo ein Eintrag fehlt. Bei fehlenden Einträgen bleibt der Cursor einfach hängen - siehe oben.

Das hat mich dazu gebracht, eine gewünschte Fehlermeldung über ein Makro zu realisieren und als Feature-Request (bei entsprechender Funktion natürlich) an Bugzilla weiter zu geben.

Ich schiebe hier einmal ein Testdokument nach. In dem Testdokument befinden sich 4 (in Englisch gehaltene) Formulare. Ich teste zur Zeit das Formular "Table_Input_required_only_Primarykey". Dabei taucht das Problem auf, dass zwar eine Meldung erstellt wird, welche Felder denn nun noch eine Eingabe benötigen. Der Cursor wird auch gesetzt. Nur verschwindet leider der vorher bereits eingegebene Inhalt, nachdem das Makro durchgelaufen ist.
Wie bekomme ich ohne großen Aufwand hin, dass der vorher geänderte Inhalt auch erhalten bleibt?

Gruß

Robert

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: So, 23.02.2014 17:03
von F3K Total
Hallo Robert,
reicht es nicht diese Zeile

Code: Alles auswählen

oForm.cancelRowUpdates
wegzulassen?
Gruß Rik

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: So, 23.02.2014 17:19
von RobertG
Hallo Rick,

wenn ich

Code: Alles auswählen

oForm.cancelRowUpdates
weg lasse, dann wird der Datensatz gespeichert und es geht zum nächsten Datensatz. Der Cursor landet dann auf dem freien Feld des folgenden Datensatzes. Ich dachte, dass vielleicht "cancel" ausreicht, aber damit habe ich auch kein Glück.

Gruß

Robert

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: So, 23.02.2014 17:24
von F3K Total
RobertG hat geschrieben:dann wird der Datensatz gespeichert
Bei mir gerade, unter W7/AOO 401, wird der Datensatz nicht gespeichert.
Gruß Rik

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: So, 23.02.2014 21:03
von RobertG
Hallo Rik,

gerade noch einmal mit dem genannten Formular überprüft. Im ersten Datensatz aus 'Hallo' ein 'Halli' gemacht. Dann weiter mit dem Tabulator. Die Meldung erscheint, dass eine Eingabe in den offenen Feldern nötig ist. Danach geht das Formular zum nächsten Datensatz und dort in das Feld, auf das der Focus eingestellt wurde - sofern cancelRowUpdates eben fehlt. Gehe ich zurück zur vorhergehenden Seite, dann ist der Eintrag 'Halli' übernommen.
Das Verhalten habe ich hier bei AOO 4.0.0 (sollte wohl einmal updaten) LO 3.3.4 und 4.1.5.3 einheitlich. - aber eben mit OpenSUSE 12.3 64bit rpm Linux.

Gruß

Robert

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: So, 23.02.2014 21:47
von F3K Total
Stimmt!
Aber, ist das nicht erlaubt? Es ist doch nur für den PK eine Eingabe erforderlich und der ist in Datensatz 1 bereits gesetzt?
Gruß Rik

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: So, 23.02.2014 22:04
von RobertG
Hallo Rik,

ich habe jetzt dafür einen Lösungsweg gefunden, der mir zwar nicht so sehr passt und auch noch nicht einwandfrei bei der Listbox funktioniert - aber sei's drum. Ich lese ja in dem Makro sowieso alle Felder aus. Da kann ich auch gleich die Werte in einem Array speichern und anschließend mit der gleichen Methode zurückschreiben. Jetzt zeigt sich beim Beenden des Makros ein Aufflackern bei den geänderten Werten, weil der Wert ja zurückgesetzt wird. Anschließend dann ein neues Setzen des Wertes. Scheint zu klappen.

Ich mache aber jetzt erst einmal Schluss und lass das etwas liegen.

Gruß

Robert

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: Di, 25.02.2014 08:42
von RobertG
Hallo Rik,
F3K Total hat geschrieben: Aber, ist das nicht erlaubt? Es ist doch nur für den PK eine Eingabe erforderlich und der ist in Datensatz 1 bereits gesetzt?
Der Primärschlüssel ist über die Datenbank als "NOT NULL" festgelegt. Die anderen Felder sind über das Formular so festgelegt, dass sie eine Eingabe benötigen. Gerade das soll ja das Makro bewirken, dass eben die Felder auch richtig gefüllt werden.
Mit dem Erstellen eines neuen Datensatzes bleibt bisher leider das Problem. Ich habe noch keine Methode gefunden, mit der ich verhindern kann, dass bei einer Neueingabe der Cursor ins nächste Formular geht. CancelRowUpdates funktioniert nur, wenn es sich um ein Update handelt, nicht aber um eine Neueingabe.

Ich hänge einmal meinen momentanen "Arbeitsstand" an.

Gruß

Robert

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: Di, 25.02.2014 21:47
von RobertG
Hallo Rik,

jetzt habe ich etwas in der API gelesen und bin (durch Zufall) fündig geworden.
Mit oForm.MoveToCurrentRow verhindere ich, dass ein Datensatz abgespeichert wird, wenn er neu erstellt wird und noch Eingaben erforderlich sind.

Jetzt kann ich erst einmal wieder beruhigt die Sache beiseite legen und mit etwas Muße dran gehen, damit das auch ordentlich beim Tabellenkontrollfeld funktioniert.

Gruß

Robert

Re: Eingabekontrolle in Formularen - Bennung fehlender Felde

Verfasst: Di, 25.02.2014 21:55
von F3K Total
Hallo Robert,
ich forsche gerade nach dem

Code: Alles auswählen

com.sun.star.sdb.XSQLErrorListener
Wenn ich die API richtig verstanden habe, sollte der sich, wenn er dem Formular zugefügt wurde, melden, bevor eine SQLException hochkommt, er meldet sich leider noch gar nicht.
invoked when a database error occurs, just before a ::com::sun::star::sdbc::SQLException is thrown to the application.
Mal sehen, ob ich da noch was finde ...
Edit: Habe leider herausgefunden, das der Listener nix macht
Edit2: Haaaalt -> er läuft ...
Edit3: Er meldet, nur wenn im Formular bei allen Feldern "Eingabe erforderlich" = nein steht, die aus der Datenbank kommende Fehlermeldung, bevor sie erscheint. Dann kann ich sie aber nicht mehr verhindern.
Hier deine Datei mit dem Listener, falls du damit etwas anfangen kannst, ich habe ihn ins Formular "Table_Input_required_all_Fields" eingebaut:

Code: Alles auswählen

global oSQLErrorListener

Sub initializeSQLErrorListener
    oSQLErrorListener = CreateUnoListener( "SQLErrorListener_", "com.sun.star.sdb.XSQLErrorListener" )
    oform = ThisComponent.drawpage.forms.MainForm
    oform.addSQLErrorListener(oSQLErrorListener)
End Sub

Sub RemoveSQLErrorListener
    oform = ThisComponent.drawpage.forms.MainForm
    oform.removeSQLErrorListener(oSQLErrorListener)
End Sub 

Sub SQLErrorListener_errorOccured(oEvent)
    xray oEvent
End Sub

Sub SQLErrorListener_disposing
end sub
Gruß Rik