AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Akzeptanz des Wertes im TField eines TDataSet

Ein Thema von Jasocul · begonnen am 3. Feb 2023 · letzter Beitrag vom 6. Feb 2023
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.337 Beiträge
 
Delphi 11 Alexandria
 
#1

Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 08:03
Folgende Situation:
Ich arbeite mit dem QuantumGrid und nutze das EditRepository, um eine Eingabe zu validieren.
Das Besondere ist, dass das zugrundeliegende Feld ein Datumsfeld ist (auch in der DB), aber die Eingabe so umgebogen ist, dass maximal nur 4 Ziffern eingegeben werden können. Diese werden im Validate geprüft und aufbereitet, damit ein gültiger Datumswert entsteht, der im DataSet dem Feld zugewiesen werden kann. Im Fehlerfall (kann nicht zum Datum aufbereitet werden) natürlich nicht.
Das funktioniert soweit gut, sofern man beim Validate den Datensatz nicht wechselt. Stehe ich aber im betroffenen Feld und will von dort den Datensatz wechseln, wird das Validate genauso abgearbeitet, wie gewünscht. Allerdings gibt es dennoch eine Exception (nicht meine Fehlermeldung), dass die 4-stellige Eingabe kein DateTime ist, was ja auch stimmt.

Soweit ich das sehen kann, liegt es am Field des DateSets, das zwar bereits den korrekten Inhalt hat, aber noch nicht als Wert akzeptiert hat.
Wechsel ich programmatisch ins nächste Feld und wieder zurück, also so eine Art Zwangsakzeptanz, gibt es keinen Fehler. Da aber der Anwender steuern kann, in welcher Reihenfolge die Felder stehen und welche editierbar sind, kann ich nicht einfach ein Feld weiter und wieder zurück, um die Akzeptenz auszulösen.
Vermutlich habe ich nur ein Brett vor dem Kopf (oder ich finde das Schlüsselwort für die Suche nicht) aber es muss doch ein Möglichkeit geben, diesen Vorgang auszulösen, ohne das Feld zu wechseln.

Kann mir bitte mal jemand auf die Sprünge helfen?
Peter
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#2

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 08:21
Es wird also irgendwo validiert, aber das nicht mit der überschriebenen "ValidierungsUndAnpassungs"-Erweiterung?
Oder wird doch deine Methode an der "richtigen" Stelle aufgerufen und die Daten kommen dennoch nicht richtig zurück?

Dann mußt du eben schauen, wo das schief geht und dann versuchen dort auf die richtige Funktion zu gehen.
Also erstmal ab der Exception, oder z.B. bei einer MessageBox manuell den Debugger anhalten, und dann im Stacktrace zurück, bis der Verursacher gefunden wurde.
Eventuell stückchenweise zurück, also mehrmals in den Fehler laufen.


Da du nicht gesagt hast, wie/wo deine Validierung/Anpassung arbeitet, würde ich jetzt auch mal ganz einfach davon ausgehen, dass dein Code auch an der falschen Stelle sein könnte und eben bei diesem Fall garnicht greifen kann. Genauso kann auch grundsätzlich der Fehler wo anders liegen, wenn im hauseigenen Delphi-Code irgendwo etwas vergessen wurde.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 3. Feb 2023 um 08:51 Uhr)
  Mit Zitat antworten Zitat
Papaschlumpf73

Registriert seit: 3. Mär 2014
Ort: Berlin
312 Beiträge
 
Delphi 12 Athens
 
#3

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 08:47
Probier mal:
DeinDataSet.UpdateRecord;
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.337 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 09:26
@Papaschlumpf73:
Klingt gut, hatte aber keine Auswirkung. Der Fehler besteht weiterhin.

Es wird also irgendwo validiert, aber das nicht mit der überschriebenen "ValidierungsUndAnpassungs"-Erweiterung?
Oder wird doch deine Methode an der "richtigen" Stelle aufgerufen und die Daten kommen dennoch nicht richtig zurück?
Im OnValidate wird eine Funktion aufgerufen, die den eingegebenen Wert analysiert und ein korrektes Datum zurückliefert, wenn es machbar war. Nur solche Fälle teste ich gerade.

Dann mußt du eben schauen, wo das schief geht und dann versuchen dort auf die richtige Funktion zu gehen.
Also erstmal ab der Exception, oder z.B. bei einer MessageBox manuell den Debugger anhalten, und dann im Stacktrace zurück, bis der Verursacher gefunden wurde.
Eventuell stückchenweise zurück, also mehrmals in den Fehler laufen.
Im Stacktrace werden keine unserer selbst geschriebenen Sourcen angesprochen:
Zitat:
:7604e292 KERNELBASE.RaiseException + 0x62
rtl.System.SysUtils.ConvertErrorFmt($50075C04,(... ))
rtl.System.SysUtils.StrToDateTime('0301',('孞嵙诃嗀卑' #$DA8B'䖉诼ﱅ堺瑒譳ﱅ䂋蕌瓀謊诓ﱍ拨'#$FFD0'诿ﱅ䂋蕄瓀荇籸琀譁籀㛨ᄌ㏿嗀챨䌎摑ヿ襤謠ﱅ 墈㍒嫀奙襤栐'#$0EE1'元䖋诼䑀䂋렻'#$FFFF'xɟ�䖋'#$FFFF'䖋裼剘奛썝 䂍唀jj噓'#$D88B'쀳桕ྨ元、搰₉쎋쫨 ̄诿䡓욋㣨ﴖ藿瓀譳䱃삅⁴횋ᛨᅯ跿ﱕ䎋ᘓ�喋诼䱃䂋 躍'#1'䎍譈ɯ�䎋譨͕�'#$0875'䎍ȓ�王蕌瓶货䎋ᗕ�喋诸'#$0846'쮋ƍ謀 䑃삅'#$0874'䂋켝'#$FFFF'쀳奚摙ႉ꽨䌏赑ʺ'#0'ǣ�xƃ�孞奙썝䂍쌀䂍匀譖 诲'#$0FD8'嚶謥诃(傑'#1'謀뺵'#$FFFF'킋쎋'#$088B'釿Ĩ'#0'䛶Ц锏裀啃 䛶Ȧ锏诂ɉ'#0'纀$'#$0C74'β쎋'#$088B'釿Ġ'#0'孞參譖诲'#$0FD8'厶譐 븃'#$FFFF'쎋ႋ鋿È'#0'킋욋糨ᄒ胿啻琀༐ᖶၴ元욋죨ᄑ༎ᖶၸ元욋루ᄑ胿养琀༑嚶ਦ簕䌐譑 붡'#$FFFF'孞ÃЀ'#0#0#0'Ȁ'#0'謀䱈즅'#$0874'螑햍'#$FFFF'蓃瓒눋 謂(ₑ'#1'쌀碀ɒੵ툳'#$088B'釿Ġ', 48, 136, 'ㆍ', #0, #0, '', ))
dbrtl.Data.DB.TDateTimeField.SetAsString('0301')
dbrtl.Data.DB.TField.SetText(???)
dbrtl.Data.DB.TField.SetEditText('0301')
:018cf72c TcxDBDataProvider.SetEditValue + $64
:00e96194 TcxCustomDataController.SetEditValue + $4C
:017ddf3b TcxCustomGridTableItem.SetEditValue + $37
:017e100e TcxGridEditingController.SetValue + $12
:017e6b43 TcxCustomGridTableController.CheckEditing + $77
:017e7184 TcxCustomGridTableController.FocusNextRecord + $24
:017e7408 TcxCustomGridTableController.FocusNextRecordWithSe lection + $28
:017e754d TcxCustomGridTableController.GoToPrev + $25
:017eecfe TcxCustomGridTableView.DoEditKeyDown + $2A
:017e067e TcxGridEditingController.DoEditKeyDown + $36
:0187f364 TcxGridTableEditingController.DoEditKeyDown + $90
vcl.Vcl.Controls.TWinControl.KeyDown(???,[ssLeft,ssRight,ssMiddle,ssDouble,ssTouch,(außerhal b der zulässigen Bereichs) 12,(außerhalb der zulässigen Bereichs) 13,(außerhalb der zulässigen Bereichs) 14,(außerhalb der zulässigen Bereichs) 15])
:50cfde43 TWinControl.KeyDown + $27
:00f11093 TcxCustomMaskEdit.KeyDown + $17
vcl.Vcl.Controls.TWinControl.DoKeyDown(???)
vcl.Vcl.Controls.TWinControl.WMKeyDown((256, (), 38, 0, (), 21495809, (), 0))
vcl.Vcl.Controls.TControl.WndProc(???)
vcl.Vcl.Controls.TWinControl.WndProc((256, 38, 21495809, 0, 38, 0, (), 1, 328, (), 0, 0, ()))
rtl.System.Classes.StdWndProc(987138,256,38,214958 09)
vcl.Vcl.Forms.TApplication.ProcessMessage(???)
:50cfdedf TWinControl.DoKeyDown + $97
Wenn da Jemand etwas sehen kann, was ich übersehe, bin ich für alles offen.

Da du nicht gesagt hast, wie/wo deine Validierung/Anpassung arbeitet, würde ich jetzt auch mal ganz einfach davon ausgehen, dass dein Code auch an der falschen Stelle sein könnte und eben bei diesem Fall garnicht greifen kann. Genauso kann auch grundsätzlich der Fehler wo anders liegen, wenn im hauseigenen Delphi-Code irgendwo etwas vergessen wurde.
Etwas vereinfachter Source der Validierung:
Delphi-Quellcode:
procedure TMeineForm.DATUMPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
// Dieses Validate bezieht sich auf ein TcxEditRepositoryMaskItem
var
   Datum: TDateTime;
begin
   inherited;

   Error := not IsDatumValid(DisplayValue, Datum); // Datum ist ein "out"

   if not Error then begin
      MycxGridDBTableView.DataController.DataSet.FieldByName('DATUM').AsDateTime := Datum;
//      MycxGridDBTableView.DataController.DataSet.UpdateRecord; // Keine Wirkung
//      MycxGridDBTableView.DataController.SetEditValue(FieldIndex, Datum, evsText); // Auch ohne Wirkung

      // Diese Springerei zwischen den Feldern wirkt, ührt aber unter Umständen zu einem erneuten OnValidate und ist auch Sch...
      if not MycxGridDBTableView.Controller.EditingController.EditingItem.IsFirst then begin
         MycxGridDBTableView.Controller.FocusNextCell(True);
      end
      else begin
         MycxGridDBTableView.Controller.FocusNextCell(False);
      end;
   end
   else begin
      ErrorText := 'Ungültiges Datum!';
      AShowInfoMessage('Ungültiges Datum!');
   end;
end;
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.993 Beiträge
 
Delphi 12 Athens
 
#5

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 09:39
Du könntest dich in das OnSetText des Fields einklinken und dort die Validierung ausführen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.337 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 10:12
Du könntest dich in das OnSetText des Fields einklinken und dort die Validierung ausführen.
Klingt nach einer Möglichkeit, die auch testen werde. Im Grunde müsste das auch die richtige Stelle sein, da ich ja einen Eingabwert erstmal in ein gültiges Datum umwandeln muss, um etwas korrektes einzutragen. Allerdings muss ich dafür relativ viel umbauen. Die Prüffunktion steht leider an einer Stelle, auf die ich im Source beim DataSet nicht ohne weiteres zugreifen kann, ohne Konzepte (die mMn an dieser Stelle auch nicht korrekt sind) über den Haufen zu werfen. Aber C&P werden mir beim Testen erstmal helfen.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#7

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 10:33
Wenn die Exception nicht in EURER Funktion ausgelöst wird, bzw. nicht durch etwas, was ihr darun aufruft, dann sind sie natürlich nicht darin aufgelistet.

Wie gesagt,
* entweder einen Haltepunkt in eure Funktion und dann Schrittweise von da bis zur Exception
* oder ab der Exception rückwärts, jeweils schauen was in den aufrufenden Methoden vorher (im Code darüber) ausgeführt wurde und ob da irgendwo eure Funktion auftaucht, bzw. ob sie dort hätte auftauchen müssen (aber vergessen wurde).

Taucht diese Exception z.B. im BeforePost oder vor dem Changed des Fields auf, dann wäre es ja verständlich, dass die Daten noch nicht gespeichert sind.



Im Validate außerhalb dem Feld etwas zuweisen
und dann hoffen es würde an der richtigen Stelle nicht wieder vom VAR DisplayValue überschrieben?

Und außerhalb am Fokus rumfummeln, ohne den aktuellen Prozess ordentlich abzubrechen? (z.B. Abort)

Außerdem mit einem Dioalog (ProcressMessages) innerhalb die Verarbeitungsreihnenfolge (andere Aktionen) reinzuholen, damit der nachfolgende Code eventuell quer schlägt.
Wenn kein Abort, dann den Dialog voa PostMessage oder ForeceQueue nach hinten verschieben.

nja, da wundert es kaum jemanden.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.337 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 10:56
entweder einen Haltepunkt in eure Funktion und dann Schrittweise von da bis zur Exception
Ws glaubst Du, woher ich den Stacktrace habe?
oder ab der Exception rückwärts, jeweils schauen was in den aufrufenden Methoden vorher (im Code darüber) ausgeführt wurde und ob da irgendwo eure Funktion auftaucht, bzw. ob sie dort hätte auftauchen müssen (aber vergessen wurde).
Ich habe bereits geschrieben, dass dort keine unserer Methoden auftaucht. Kannst Du mir glauben oder auch lassen. Ansonsten selbst den Stacktrace ansehen. Dafür habe ich ihn hier reinkopiert.
Taucht diese Exception z.B. im BeforePost oder vor dem Changed des Fields auf, dann wäre es ja verständlich, dass die Daten noch nicht gespeichert sind.
Der Wert ist laut Source/Debugger verändert. Der Fehler entsteht nach jetzigem Stand im SetText des Feldes. Vermutlich im BeforePost.

Im Validate außerhalb dem Feld etwas zuweisen
und dann hoffen es würde an der richtigen Stelle nicht wieder vom VAR DisplayValue überschrieben?
Wenn Du die Komponente und das Validate dieser Komponente dann auch nicht, dann kann ich erhlich gesagt, auf Deine Infos verzichten. Aber trotzem eine kurze Erläuterung: Das DisplayValue dient nur der internen Nutzung, wenn die Komponente selbst eine Fehlermeldung ausgibt. Das ist aber für meine Zwecke nicht brauchbar. Der tatsächliche DisplayValue bleibt unverändert.

Und außerhalb am Fokus rumfummeln, ohne den aktuellen Prozess ordentlich abzubrechen? (z.B. Abort)
Und was glaubst Du, warum ich nach einer anderen Lösung suche? Abgesehen davon verwirft ein Abort die Änderungen des kompletten Datensatzes und nicht nur die des Feldes.

Außerdem mit einem Dioalog (ProcressMessages) innerhalb die Verarbeitungsreihnenfolge (andere Aktionen) reinzuholen, damit der nachfolgende Code eventuell quer schlägt.
Wenn kein Abort, dann den Dialog voa PostMessage oder ForeceQueue nach hinten verschieben.
Habe ich bereits versucht, ändert aber nichts am Problem.

nja, da wundert es kaum jemanden.
Ein wenig arrogant, der Herr.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.337 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 12:18
Problem behoben.
Uew Raabe hat mich auf den richtigen Weg gebracht. Danke dafür. Die Kompontenten arbeiten alle korrekt. Eines unserer Konzepte hat in einem besonderen Fall immer wieder dafür gesorgt, dass der Wert zurückgesetzt wurde. Das war allerdings nicht über den Callstack ersichtlich.

Nachdem ich dieses unsinnige Verhalten im Konzept berücksichtigt habe, kann ich das Validate ganz normal ausführen und muss dort auch nicht mehr direkt den validierten Wert ins DataSet eintragen. Nächste Woche werde ich erstmal ein Refactoring des Konzepts beantragen.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#10

AW: Akzeptanz des Wertes im TField eines TDataSet

  Alt 3. Feb 2023, 18:29
Sorry, war nur ein leicht schnippiger Hinweis darauf, dass man sich über ungünstigen Code
(beim Application.ProcessMessages wird von Vielen oft davor gewarnt, aber auch Dialoge sind diesbezüglich nicht besser / noch schlimmer)
Vieles sinnlos zusätzlich kaputt machen kann.
ShowMessage im Form.OnClose/OnDestroy ist auch so ein geiler Fall. (hier nur andersrum, weil man sich gern wundern darf, wenn der Dialog oft nahezu sofort wieder geschlossen wird, da das gehende Fenster ihn mit nimmt)

Es geht selten gut aus, wenn sich in komplexere Abläufe, welche eine bestimmte Reihenfolge haben müssen,
plötzlich Pausen und die Verarbeitung von Messages ala Repaint, Timern, Tastatur, Maus usw. reindrängeln vordrängeln.



Der Stacktrace ist auch nicht "was aufgerufen wurde", sondern "wie es zurück geht".

Man darf also nicht vergessen, dass dort die Rücksprungadresse drin steht und es eigentlich einer der Befehle davor war.
(der Debugger vertut sich auch manchmal und zeigt auf eine Codezeilen weiter unten)

Code:
A
  B
    C
      D < hier der eigentliche Gund für den Fehler
    E < hier ging es wegen dem Fehler rein
      F
        G < hier knallt es
    E < wird nie aufgerufen
Der CallStack sagt A-B-E-F-G aber wenn man C und D wissen will, muß man manuell im Code nachsehn
oder sich über nochmaliges/mehrermaliges Auslösen und Haltepunkte+F7/F8 durcharbeiten.
Hier also irgendwann beim Aufruf von E im B zum Anfang und von da dann schrittweise weiter, bis spätestens, wo es kallt)



Auch Fehler anzeigen mit ShowMessage rächt sich nicht nur hier, sondern auch anderswo,
z.B. wenn man versucht eine Funktion von wo anders aufzurufen (Code wiederverwenden), da mit try-except versucht auf Fehler zu reagieren, um optional was Anderes zu machen.

Außer wenn in einer wirklich endgültigen Funktion ein Fehler ausgegeben werden muß, um anschließend weiter zu arbeiten,
am Besten grundsätzlich Fehler immer per RAISE abgeben.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz