Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Kontrolle, ob eine Variable im Record geändert wurde. (https://www.delphipraxis.net/184082-kontrolle-ob-eine-variable-im-record-geaendert-wurde.html)

bernau 24. Feb 2015 11:42

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:
type
  TMeinDatenRecord = record
    Nachname:String;
    Vorname:String;
    Geb:TDatetime;
    IrgendeineNummer:integer;
  end;
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.

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;

stahli 24. Feb 2015 11:46

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.

bernau 24. Feb 2015 11:48

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.

Der schöne Günther 24. Feb 2015 11:51

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.

p80286 24. Feb 2015 11:57

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

stahli 24. Feb 2015 12:01

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...

himitsu 24. Feb 2015 12:36

AW: Kontrolle, ob eine Variable im Record geändert wurde.
 
Zitat:

Zitat von p80286 (Beitrag 1291270)
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.

Siehe dein Vorredner :zwinker:

Ja, seit Delphi 2006 / Turbo Delphi.
Und das
Delphi-Quellcode:
strict
kam noch ein bissl später.

http://geheimniswelten.de/sonstiges/delphi-compiler/

p80286 24. Feb 2015 13:47

AW: Kontrolle, ob eine Variable im Record geändert wurde.
 
:oops::oops::oops:
schäm!

K-H

bernau 25. Feb 2015 09:03

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 13:52 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