![]() |
Kontrolle, ob eine Variable im Record geändert wurde.
Mal wieder Brainstorming
Gegeben ist ein Record (Beispiel - Kann auch irgend eine andere Datenstruktur sein)
Delphi-Quellcode:
Der Datenrecord wird mit Daten gefüllt und somit in einen Ausgangszustand versetzt. Dann soll dieser Record einer Procedure übergeben werden. Dort können einzelne Felder geändert werden.
type
TMeinDatenRecord = record Nachname:String; Vorname:String; Geb:TDatetime; IrgendeineNummer:integer; end; Wie finde ich nun am bessten (und ohne grossen Aufwand) heraus, welches Feld geändert wurde? Kann natürlich eine Kopie des Records anlegen und diesen dann vergleichen. Oder sollte ich lieber Objekte verwenden und dort ein ChangeFlag im Setter setzen? Oder kann ich mir einen Typen deklarieren, den ich wie einen Standardtypen verwenden kann aber erweiterte funktionen hat. In folgender Art:
Delphi-Quellcode:
var
MyString:TStringExtended; begin MyString.IsNull := true; // Kein Inhalt MyString:='Ein Text'; IstGeaendert := MyString.IsChanged; end; |
AW: Kontrolle, ob eine Variable im Record geändert wurde.
Ist eine Lösung für diesen Record in einer Bearbeitungsfunktion gesucht oder ein genereller Ansatz für eine komplette Anwendung.
Diese Unterscheidung ist nicht unwichtig. Für eine lokale Prüfung würde ich eine Kopie anlegen und vergleichen. Wenn Du eine Lösung für viele Records/Daten in einem gesamten Projekt suchst, reicht das natürlich nicht. |
AW: Kontrolle, ob eine Variable im Record geändert wurde.
Vier Minuten für die Antwort. Bin immer wieder erstaunt. :-D
Es geht um den Grundsätzlichen Ansatz. Es wird viele verschiedene Recordtypen (bzw. Datenstrukturen) geben. |
AW: Kontrolle, ob eine Variable im Record geändert wurde.
Mach doch einfach keine direkten Variablen sondern Properties. Das Setzen der Property setzt ein "was Changed"-Flag auf True das du abfragen kannst.
Delphi-Quellcode:
program Project22;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type TMyRecord = record strict private var FSomeName: String; FIsChanged: Boolean; strict private function GetSomeName(): String; procedure SetSomeName(const Value: String); public function isChanged(): Boolean; procedure resetChangedFlag(); property SomeName: String read GetSomeName write SetSomeName; end; { TMyRecord } function TMyRecord.GetSomeName(): String; begin Result := FSomeName; end; function TMyRecord.isChanged(): Boolean; begin Result := FIsChanged; end; procedure TMyRecord.resetChangedFlag(); begin FIsChanged := False; end; procedure TMyRecord.SetSomeName(const Value: String); begin if Value.Equals(FSomeName) then Exit; FIsChanged := true; FSomeName := Value; end; var myRecord: TMyRecord; begin try Write('record is changed: '); WriteLn( myRecord.isChanged() ); myRecord.SomeName := 'Hallo Welt'; Write('record is changed: '); WriteLn( myRecord.isChanged() ); myRecord.resetChangedFlag(); Write('record is changed: '); WriteLn( myRecord.isChanged() ); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; readln; end. |
AW: Kontrolle, ob eine Variable im Record geändert wurde.
Mit den neueren Delphis bin ich nicht so fit, aber es soll doch da in der Zwischenzeit so etwas wie Record-Methoden geben, dann baust Du Dir einen Setter, der das Edited-Flag setzt und gut ist.
Gruß K-H |
AW: Kontrolle, ob eine Variable im Record geändert wurde.
Ja, hatte eh keinen Mittagsschlaf gemacht heute. ;-)
Dann bist Du mit Klassen auf jeden Fall besser bedient. Über Getter und Setter kannst Du dann auf die realen gespeicherten Daten gehen. Auch kannst Du dort auf Änderungen reagieren und Abonnenten über Änderungen informieren (Stichwort: Databinding oder MVVM). Sind alle Daten die gesamte Projektlaufzeit im Speicher verfügbar oder brauchst Du so etwas wie einen ORM? Du musst Dir halt genau überlegen, wie Du arbeiten und was Du erreichen willst. Es gibt da mit Sichheit mehrere mögliche Ansätze. Wer soll denn eigentlich erfahren, dass etwas geändert wurde (sicher die GUI-Controls, oder?) und können das auch mehere Konsumenten sein? Wenn z.B. Formular1 die Darstellung aktualisiert hat und IsChanged zurück setzt, dann kann Formular2 die Änderung nicht mehr erkennen. Also da muss man wohl genau wissen, was Du im Detail umsetzen willst. Vielleicht kannst Du Dir ja bei meinem ssFramework oder bei DSharp schon mal Anregungen holen... |
AW: Kontrolle, ob eine Variable im Record geändert wurde.
Zitat:
Ja, seit Delphi 2006 / Turbo Delphi. Und das
Delphi-Quellcode:
kam noch ein bissl später.
strict
![]() |
AW: Kontrolle, ob eine Variable im Record geändert wurde.
:oops::oops::oops:
schäm! K-H |
AW: Kontrolle, ob eine Variable im Record geändert wurde.
Die Antwort vom Schönen Günter ist wohl das Besste für mich.
Ich denke, so werde ich es verwenden.
Delphi-Quellcode:
program DataRecord;
{$APPTYPE CONSOLE} uses SysUtils; type TDataItemString = record private fValue: string; fChanged: boolean; fIsNull: Boolean; procedure SetValue(const Value: string); procedure SetIsNull(const Value: Boolean); public property Value: string read FValue write SetValue; property IsNull: Boolean read FIsNull write SetIsNull; function Changed: Boolean; procedure ResetChanged; end; TDataAdresse = record nachname: TDataItemString; Vorname: TDataItemString; Strasse: TDataItemString; procedure ResetChanged; function RecordChanged: boolean; end; { TDataItemString } function TDataItemString.Changed: Boolean; begin Result := fChanged; end; procedure TDataItemString.ResetChanged; begin fChanged := False; end; procedure TDataItemString.SetIsNull(const Value: Boolean); begin FIsNull := Value; end; procedure TDataItemString.SetValue(const Value: string); begin if fIsNull or (not SameStr(Value,fValue)) then begin FValue := Value; fChanged := True; fIsNull := False; end; end; { TDataAdresse } function TDataAdresse.RecordChanged: boolean; begin Result := nachname.Changed or Vorname.Changed or Strasse.Changed; end; procedure TDataAdresse.ResetChanged; begin nachname.ResetChanged; Vorname.ResetChanged; Strasse.ResetChanged; end; var lataAdresse: TDataAdresse; begin lataAdresse.nachname.Value := 'Meier'; lataAdresse.Vorname.Value := 'Hans'; lataAdresse.Strasse.Value := 'Hauptstr'; lataAdresse.ResetChanged; lataAdresse.Vorname.Value := 'Peter'; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:57 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz