{Gelöst] Pflichtfelder prüfen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Ich934
Lazarusforum e. V.
Beiträge: 317
Registriert: So 5. Mai 2019, 16:52
OS, Lazarus, FPC: ArchLinux und Windows mit FPCUPdeluxe (L: 2.0.X, FPC 3.2.0)
CPU-Target: x86_64, i386
Wohnort: Bayreuth

{Gelöst] Pflichtfelder prüfen

Beitrag von Ich934 »

Hallo,

ich habe hier mal eine etwas kompliziertere Frage und hoffe, ich kann mein Problem so schildern, dass es verständlich ist.

Lazarus 3.0
FPC 3.2.2
Datenbank: SQLite
Zugriff via LiteDAC

Es handelt sich um eine komplexere Anwendung, welche mehrere Tabellen in der Oberfläche darstellt. Da auch eine grafische Anzeige erfolgt, muss bei der Neuanlage der Hauptdatensatz leer angelegt werden, ohne dass hier plausible Daten vorhanden sind. Es ist also nur eine ID verfügbar und ggf. entsprechende Referenzen, wenn diese angelegt werden.

Bei „richtigen“ Speichern soll jetzt die Plausibilitätsprüfung erfolgen. Dazu habe ich eine entsprechende Funktion geschrieben, die das erledigt. Bei der Tabelle (in diesem Fall eine TLiteTable-Komponente) erfolgt diese Prüfung im BeforePost-Ereignis, was auch so funktioniert, wie ich es erwarte.

Ein Problem gibt es, wenn man über den TDBNavigator navigiert. Hier erfolgt keine Prüfung auf Plausibilität und man kommt zu einem anderen Datensatz. Mein Ansatz war jetzt, im Ereignis BeforeScroll ebenfalls die Plausibilität zu prüfen. Allerdings knallt das bei der Neuanlage eines Datensatzes, da ich zur Prüfung das DataSet verwende. Gibt es eine Möglichkeit zu prüfen, ob das sich gerade im Create befindet oder muss ich mir hier ein Hilfskonstrukt bauen?

Ich hoffe, das Ganze ist verständlich. Vielen Dank schon mal.
Zuletzt geändert von Ich934 am So 10. Mär 2024, 15:47, insgesamt 1-mal geändert.
Tipp für PostgreSQL: www.pg-forum.de

LazarusFuchs
Beiträge: 16
Registriert: Mo 19. Aug 2013, 22:28

Re: Pflichtfelder prüfen

Beitrag von LazarusFuchs »

Im DBNavigator im Click Ereignis eine entsprechende Routine einbauen:

procedure TFormMain.DBNavigatorItemsClick(Sender: TObject; Button: TDBNavButtonType);

Button enthält den entsprechenden Button:
TDBNavButtonType = (nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete, nbEdit, nbPost, nbCancel, nbRefresh); // https://lazarus-ccr.sourceforge.io/docs ... ntype.html

Den Status der Datenbanktabelle kann man hiermit abfragen:
DataSet.State ist in TDataSetState enthalten https://www.freepascal.org/docs-html/fc ... state.html

// Abfrage, welche Taste im Navigator gedrückt wurde und ob ob die Datenbank im Insert-Modus ist
procedure TFormMain.DBNavigatorItemsClick(Sender: TObject; Button: TDBNavButtonType);
if (Button = nbPost) und (DataSourceX.State = dsInsert) then begin
Prüfroutine
end;


Abfrage mehrer Zustände in DataSource:
if DataSourceX.State in [dsEdit, dsInsert] then

Abfrage mehrer Buttons:
if Button in [nbPost, nbPrior., nb...] then

In "if (Button=nbPost)" können selbstverständlich auch mehrere Buttons überprüft werden. Bei dieser Abfrage kann ich mir vorstellen dass überhaupt auf keinen Button Bezug genommen wird, sonder nur abgefragt wird ob die Tabelle im dsInsert-Modus ist.

Wie sich das auf die andere Prüfroutine auswirkt kann ich nicht sagen, aber da sie nicht angestoßen wird wahrscheinlich keine Auswirkung. Sonst könnte man mit einer boolschen Variable das so steuern, dass die andere Routine nicht aufgerufen wird.

Ich934
Lazarusforum e. V.
Beiträge: 317
Registriert: So 5. Mai 2019, 16:52
OS, Lazarus, FPC: ArchLinux und Windows mit FPCUPdeluxe (L: 2.0.X, FPC 3.2.0)
CPU-Target: x86_64, i386
Wohnort: Bayreuth

Re: Pflichtfelder prüfen

Beitrag von Ich934 »

Danke. Das funktioniert leider nicht. Zwar kann ich hier problemlos die Buttons prüfen, im DataSet stehen aber schon die Daten des neuen Datensatzes. Sprich die Prüfung kommt hier zu spät.
Tipp für PostgreSQL: www.pg-forum.de

LazarusFuchs
Beiträge: 16
Registriert: Mo 19. Aug 2013, 22:28

Re: Pflichtfelder prüfen

Beitrag von LazarusFuchs »

MouseDown? das wäre noch bevor gepostet wird, oder

procedure TFormShowRxDBGrid.DBNavigator1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

Joh
Lazarusforum e. V.
Beiträge: 191
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: Pflichtfelder prüfen

Beitrag von Joh »

Die Frage ist doch eher: warum sollte ich navigieren können, wenn ein Datensatz noch nicht gespeichert ist...

Solange der Datensatz nicht gespeichert ist, werden die Button Anfang, vor, zurück und Ende deaktiviert und fertig.

ro steht bei mir für die Variable ReadOnly, die übergeben wird.
Da bei mir das kopieren am wichtigsten ist, habe ich allerdings nicht den DB-Navigator sondern eigene Objekte genutzt.
SetReadOnly wird bei jeder Datensatzbewegung, Änderung aufgerufen.

Code: Alles auswählen

procedure SetReadOnly(ro: Boolean);
begin
  btnErster.Enabled := ro;
  btnVorheriger.Enabled := ro;
  btnNaechster.Enabled := ro;
  btnLetzter.Enabled := ro;
  btnEinfuegen.Enabled := ro;
  btnKopieren.Enabled := ro;
  btnEdit.Enabled := ro;
  btnLoeschen.Enabled := ro;
  btnSpeichern.Enabled := NOT ro;
  btnAbbrechen.Enabled := NOT ro;
end;
just my two Beer

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: Pflichtfelder prüfen

Beitrag von wp_xyz »

Das ist alles der falsche Ansatz. Egal wie die Eingabe begonnen wurde, durch den DBNavigator, oder in einer Zelle des Grid, oder in einem TDBEdit, die Kontrolle liegt immer bei der Datenbank, nie bei den Eingabeelementen. TField hat ein Event OnValidate, in dem man die Eingabe prüfen kann, wenn der Feld-Editor verlassen wird, und TDataset hat das Event OnBeforePost, in dem man die Konsistenz des ganzen Records checken kann. Im fall eines Fehlers zeigt man eine Fehlermeldung an und ruft "Abort" auf, wodurch die akuell laufende Aktion unterbrochen wird (wahrscheinlich geht auch, eine Exception zu feuern, aber da nervt mich, dass die Arbeit in der IDE dadurch unterbrochen wird).

Es ist dann egal, ob der geänderte Record durch den Post-Button im DBNavigator oder duch Drücken von ENTER, oder durch Anwählen eines anderen Records gespeichert werden soll - diese Prüfung wird immer aufgerufen. Man kann im Fehler-Fall den Bearbeitungszustand nur durch Drücken von ESC oder Anklicken des Cancel-Buttons im Navigator beenden.

Im beigefügten Beispiel hat eine Datenbank zwei Float-Felder x und y. In beiden Feldern sind nur positive Zahlen erlaubt, und zwar so, dass die Summe der Quadrate von x und y kleiner als zwei ist. Das OnValidate-Event prüft die erste, und das OnBeforePost-Event prüft das zweite Kriterium. Außerdem gibt es noch ein OnCloseQuery-Event des Formulars, das verhindert, dass man die Anwendung schließt, wenn gerade ein Record bearbeitet wird.
Dateianhänge
bufds_validation.zip
(2.72 KiB) 64-mal heruntergeladen

Benutzeravatar
gladio
Beiträge: 217
Registriert: Sa 21. Jun 2014, 06:15
OS, Lazarus, FPC: Win10-64 - aktuelle Lazarus/FPC Standard-Edition
CPU-Target: 64Bit
Wohnort: Rügen

Re: Pflichtfelder prüfen

Beitrag von gladio »

Wenn man Eingaben prüfen möchte, bevor siie in eine Datenbank geschrieben werden, bieten sich Eingabeelemente an, die nicht direkt mit der Datenbank kommunizieren an.
Also anstatt direkt über ein TDBEdit, die Eingabe in ein TEdit, die Eingabe prüfen und wenn alles stimmt in die Datenbankfelder übertragen.

Ich934
Lazarusforum e. V.
Beiträge: 317
Registriert: So 5. Mai 2019, 16:52
OS, Lazarus, FPC: ArchLinux und Windows mit FPCUPdeluxe (L: 2.0.X, FPC 3.2.0)
CPU-Target: x86_64, i386
Wohnort: Bayreuth

Re: Pflichtfelder prüfen

Beitrag von Ich934 »

@wp_zyz: Das mit den OnValidate ist eine gute Option. Das werde ich mal näher prüfen. Danke für das Beispiel.

@gladio: Löst das Problem nicht. Auch hier muss entsprechend reagiert und die Daten übernommen werden. Mein Problem ist an einer ganz bestimmten Stelle die vorhandene Prüfung aufzurufen und dann abzubrechen.
Tipp für PostgreSQL: www.pg-forum.de

Benutzeravatar
six1
Beiträge: 788
Registriert: Do 1. Jul 2010, 19:01

Re: Pflichtfelder prüfen

Beitrag von six1 »

Ganz, ganz früher, habe ich das auch über direkte Eingaben in Tabellen und Datasource States gelöst.
Dies wird aber schnell unübersichtlich bei möglichen Erweiterungen oder Änderungen.
Ich habe dann irgendwann damit angefangen, eine Form zu gestalten, welche die Eingabedaten über Edits, Spinedits o.ä. abfragt.
Diese Form kann dann zum Ändern vorhandener oder auch zur Eingabe von Daten für einen neuen Datensatz verwendet werden.
Gruß, Michael

Ich934
Lazarusforum e. V.
Beiträge: 317
Registriert: So 5. Mai 2019, 16:52
OS, Lazarus, FPC: ArchLinux und Windows mit FPCUPdeluxe (L: 2.0.X, FPC 3.2.0)
CPU-Target: x86_64, i386
Wohnort: Bayreuth

Re: Pflichtfelder prüfen

Beitrag von Ich934 »

Hallo,

ich möchte hier jetzt noch etwas nachtragen, was mir die Lösung dann gebracht hat: der DBNavigatior hat eine BeforeAction-Prozedur, die genau dann greift, wenn ich das benötige. Dort können auch, wie oben schon vorgeschlagen, die Buttons abgefragt werden. Meine Prüfroutine prüft und wenn diese fehlschlägt, dann wird abgebrochen.

Im Vorfeld passiert das schon, wenn die entsprechenden Fehler bei der Eingabe leer verlassen werden.

Vielen Dank für die Hinweise.
Tipp für PostgreSQL: www.pg-forum.de

Antworten