AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Record, der überschrieben wird, bekommt wieder Initialwerte

Record, der überschrieben wird, bekommt wieder Initialwerte

Ein Thema von marfin777 · begonnen am 23. Jul 2015 · letzter Beitrag vom 27. Jul 2015
Antwort Antwort
marfin777

Registriert seit: 23. Jul 2015
5 Beiträge
 
Delphi XE8 Professional
 
#1

Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 23. Jul 2015, 15:41
Delphi-Version: XE8
Hallo Community,

mein erster Beitrag also...
Meine Kenntnisse in Delphi sind ansich mager, aber ich arbeite seit langem mit verschiedensten Programmiersprachen.

Umgebung
Ich schreibe ein GUI zum Erstellen von Regeln zur automatischen Probenentnahme an einer Produktionsschiene.
Ca. 20 Parametern zum Kunden, Artikel und verwendeten Materialien halte ich hierzu in einer Oracle-Tabelle.

Unit1 sei somit meine Form zur Eingabe/Anzeige, Unit2 der Datencontainer ohne Methoden und Unit3 die Methoden, die z.B. zur Umwandelung von dem einen Record in den anderen Record zuständig sind.

Ich habe mich dazu entschieden, mit 2 Arten von Records zu arbeiten. Einer, der vergleichbare Variablen und Datentypen hat, wie die Oracle-Tabelle und einer, der auf die Felder des GUI zugeschustert ist.

Demnach arbeite ich mit 2 Records: aus DB einlesen (Typ1) und für GUI aufarbeiten (Typ2).
Natürlich ist die ganze Sache etwas komplexer, aber da sehe ich mal keine Zusammenhänge zu meinem Problem.

Delphi-Quellcode:
 (Unit2)
type TDbRegeln = Record // Record mit Variablen und Formaten der DB-Tabelle
  Probenart_Nr: Integer;
  Probenart_Txt: String;
  (...)
  Proben_Zaehler: Integer;
end;
Delphi-Quellcode:
 (Unit2)
type TComboBoxList = array [0..7] of String; // Array für die 8 anzuzeigenden Elemente einer TComboBox

type TRegeln = record // Record mit Variablen und Formaten der Masken-Regeln
  ProbenartNr: String;
  ProbenartNrList: TComboBoxList;
  ProbenartNrVer: String;
  Aktiv: Boolean;
  GrundAenderung: String;
  ProbenartText: String;
  (...)
  Artikel: String;
  ArtikelList: TComboBoxList;
  StatusIndex: Integer;
  Status: Integer;
  UnsavedChanges: Boolean;
  UnsavedChangesNr: Boolean;
  UnsavedChangesNrVer: Boolean;
end;
Delphi-Quellcode:
 (Unit2)
AktRegel: TRegeln;
LoadRegel: TDbRegeln;
Problem
In Unit1 werden zum FormCreate Initialwerte für AktRegel.* gesetzt. Eigentlich nur zum debuggen, da ich kurz darauf, immer noch im FormCreate via Devart's Oracle-Direct Schnittstelle die letzte aktive Regel in der Oracle-DB abrufe und an LoadRegel.* übergebe.
Diese wird (Soweit ich das im Debugging verfolgen kann) auch korrekt in LoadRegel eingelesen. Anschließend werden die Daten in Unit3 "procedure DbRecordToDataset" aufbereitet zur Anzeige im GUI und zeilenweise an AktRegel weitergegeben.
Den gesamten folgenden Code aus Unit3 kann ich im Debugger mit F8 ja ganz gut verfolgen und die Werte der Variablen, sowohl von LoadRegel.*, als auch die übergebenen Werte an AktRegel.* sind korrekt.
Nachdem allerdings die procedure durchgelaufen ist und zum Aufrufer (Unit1.FormCreate) zurückspringt, ist AktRegel wieder mit den Initialwerten gefüllt! Was weiss ich da noch nicht?

(Unit1) procedure FormCreate
(Unit1) Initialwerte setzen
(Unit1) LoadRegel.* mit UniQuery-Daten füllen
(Unit1) Unit3.DbRecordToDataset aufrufen
(Unit3) LoadRegel.* verarbeiten zu AktRegel.*
(Unit3) Zurück zum Aufrufer Unit1.FormCreate
(Unit1) AktRegel.* ist wieder mit Initialwerten gefüllt

Delphi-Quellcode:
procedure DbRecordToDataset;
  var
    StrBba: String;
begin
  AddListItem(AktRegel.ProbenartNrList, AktRegel.ProbenartNr); //Methode um die TComboBox-Listen zu füllen
  AddListItem(AktRegel.ProbenartNrVerList, AktRegel.ProbenartNrVer);
  AddListItem(AktRegel.ProbenZyklusList, AktRegel.ProbenZyklus);
  AddListItem(AktRegel.WiederholenList, AktRegel.Wiederholen);
  AddListItem(AktRegel.KundenNrList, AktRegel.KundenNr);
  AddListItem(AktRegel.KundeList, AktRegel.Kunde);
  AddListItem(AktRegel.SystemList, AktRegel.System);
  AddListItem(AktRegel.MaterialList, AktRegel.Material);
  AddListItem(AktRegel.ArtikelList, AktRegel.Artikel);

  AktRegel.ProbenartNr := IntToStr(LoadRegel.Probenart_Nr);
  AktRegel.ProbenartNrVer := COPY(IntToStr(LoadRegel.Probenart_Nr_Ver)
        ,(Length(IntToStr(LoadRegel.Probenart_Nr_Ver))-2),3);
  AktRegel.ProbenartDatNeu := LoadRegel.Probenart_Dat_Neu;
  AktRegel.ProbenartDatAender :=LoadRegel.Probenart_Dat_Aender;
  AktRegel.GrundAenderung := LoadRegel.Grund_Aenderung;
  AktRegel.AnzahlProben := IntToStr(LoadRegel.Anzahl_Tafeln);
  AktRegel.ProbenZyklus := IntToStr(LoadRegel.Proben_Zyklus);
  AktRegel.Wiederholen := IntToStr(LoadRegel.Wiederholen);
  AktRegel.Bemerkung1 := LoadRegel.Bemerkungen_Zeile_1;
  AktRegel.Bemerkung2 := LoadRegel.Bemerkungen_Zeile_2;
  AktRegel.KundenNr := IntToStr(LoadRegel.Kunden_Nr);
  AktRegel.DickeVon := (GetDickeDb(LoadRegel.Gesamt_Dicke_Von));
  AktRegel.DickeBis := (GetDickeDb(LoadRegel.Gesamt_Dicke_Bis));
  AktRegel.Material := IntToStr(LoadRegel.Material);
  AktRegel.Artikel := IntToStr(LoadRegel.Artikel);
  AktRegel.StatusIndex := GetStatus(LoadRegel.Artikel_Status);
  AktRegel.DurchlaufIndex := GetDurchlaufIndex(LoadRegel.Durchlauf);
  AktRegel.ProbenartTextIndex := GetProbenartTxt(LoadRegel.Probenart_Txt);
  AktRegel.Kunde := GetCustomer(LoadRegel.Kunden_Nr);
  AktRegel.VmArtIndex := GetVMaterial(LoadRegel.Vm_Art);
  AktRegel.System := IntToStr(LoadRegel.System)
                    + ' - '
                    + GetSystem(LoadRegel.System);
  AktRegel.UnsavedChangesNr := False;
  AktRegel.UnsavedChangesNrVer := False;
  AktRegel.UnsavedChanges := False;

  StrBba:= AnsiUpperCase(TRIM(LoadRegel.Bba));

  case AnsiIndexStr(StrBba,['3', '4']) of
  0:begin
      AktRegel.Bba3:=true;
      AktRegel.Bba4:=false;
    end;
  1:begin
      AktRegel.Bba4:=true;
      AktRegel.Bba3:=false;
    end;
  else
    begin
      AktRegel.Bba4:=true;
      AktRegel.Bba3:=true;
    end;
    AktRegel.Bba := StrToIntDef(LoadRegel.Bba,0);
  end;

  case LoadRegel.Regel_Aktiv of
  0: AktRegel.Aktiv:= false;
  else
    AktRegel.Aktiv:= true;
  end;

  HinweisTextNeu('Datensatz '
                + AktRegel.ProbenartNr
                + ' v'
                + AktRegel.ProbenartNrVer
                + ' geladen');
end;
Danke für's lesen und sonnige Grüße, Markus
Markus
  Mit Zitat antworten Zitat
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 23. Jul 2015, 16:24
Sind denn in der Unit2 die Variablen global deklariert?

Delphi-Quellcode:
unit Unit2;

Interface

...

var
  AktRegel: TRegeln;
  LoadRegel: TDbRegeln;

implementation

...
Oder hat die Unit1 vielleicht versehentlich auch eine lokale Variable Namens AktRegel?
Hinter dir gehts abwärts und vor dir steil bergauf ! (Wolfgang Ambros)
  Mit Zitat antworten Zitat
CarlAshnikov

Registriert seit: 18. Feb 2011
Ort: Erfurt
108 Beiträge
 
Delphi XE5 Enterprise
 
#3

AW: Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 24. Jul 2015, 07:57
Mir ist schon manchmal das Problem auf die Füsse gefallen, dass ich nicht mit dem original Record gearbeitet habe, sondern mit einer Kopie. Das passiert z.B. dann wenn das Record nicht als var Parameter übergeben wird procedure SchreibWasInMeinRecord(ARec: TMeinTollesRecord); oder als Rückgabewert einer Funktionfunction GibMirDeinRecord: TMeinTollesRecord; . Anders als bei Objekten kriegst du da keine Referenz und musst das im Ganzen wieder dort zuweisen wo du die Werte haben willst.

Das kann bei der Verwendung globaler Variablen nicht passieren. Ansonsten sind die natürlich zu vermeiden wie du sicher weißt .

Sollte das nicht der Fall sein, schreib dir Setter für deine Record Felder und setze dort einen Breakpoint, dann solltest du sehen wer dir da deine Werte zurücksetzt.

Delphi-Quellcode:
type TRegeln = record
private
  fProbenArtNr: String;
  procedure SetProbenArtNr(AValue: String);
public
  property ProbenArtNr: String read fProbenArtNr write SetProbenArtNr;
end;

Procedure TRegeln.SetProbenArtNr(AValue: String);
begin
  fProbenArtNr := AValue; //<-- Breakpoint
end;
Sebastian
Das kann ja wohl nicht var sein!
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.288 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 24. Jul 2015, 09:59
Ich würde eher Klassen daraus machen und DbRecordToDataset als Methode der Klasse implementieren, einfach als Zuweisung, also Assign. Dann kann man das wunderbar in der Klasse kapseln...
Delphi-Quellcode:
AktRegel.Assign(LoadRegel);
//
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 24. Jul 2015, 10:53
Auch wenn eigentlich schon darauf hingewiesen wurde
Zitat:
(Unit3) LoadRegel.* verarbeiten zu AktRegel.*
(Unit3) Zurück zum Aufrufer Unit1.FormCreate
(Unit1) AktRegel.* ist wieder mit Initialwerten gefüllt
Eine Variable mit dem Namen XXXX wird im ersten Schritt mit den Gewünschten Daten gefüllt.
Eine Variable mit dem Namen YYYY enthält nicht die übertragenen Werte obwohl XXXX und YYYY die selbe Variable sein sollte?
Wenn Du das debuggst solltest Du gleichzeitig den Inhalt von YYYY und XXXX überwachen, denn der müßte der selbe sein!
Ist das nicht der Fall hast Du nicht nur unterschiedliche Namen sondern auch unterschiedliche Variablen.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
marfin777

Registriert seit: 23. Jul 2015
5 Beiträge
 
Delphi XE8 Professional
 
#6

AW: Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 27. Jul 2015, 10:07
So... entschuldigt die verspätete Antwort, aber am Wochenende kam ich zu nix...

Zitat:
Sind denn in der Unit2 die Variablen global deklariert?
- Deklaration ausschließlich in unit2 unter interface.

Zitat:
...Das passiert z.B. dann wenn das Record nicht als var Parameter übergeben wird
- Diese spezielle Prozedur zum Umwandeln, und auch die meisten anderen "Methoden", die den record verändern arbeiten ohne Übergabe- oder Rückgabewerte.

Zitat:
Ich würde eher Klassen daraus machen und DbRecordToDataset als Methode der Klasse implementieren, einfach als Zuweisung, also Assign. Dann kann man das wunderbar in der Klasse kapseln...
- So werd ich's jetzt umbauen! auch wenn ich damit noch nicht ganz nachvollziehen konnte, warum sich der Record, wie beschrieben, verhielt. Am Anfang war's ein übersichtlicher record mit einer handvoll Variablen, aber nach-und-nach kam vom beauftragenden Fachbereich immer mehr dazu.
Mit Klassen und Methoden fühl ich mich eh direkt etwas vertrauter.

Zitat:
Eine Variable mit dem Namen YYYY enthält nicht die übertragenen Werte obwohl XXXX und YYYY die selbe Variable sein sollte?
- Wenn ich dich richtig verstanden habe, hast du mich missverstanden. Die Records werden ausschließlich in Unit2 gebildet und in Unit3 von Record-Typ TRegeln in TDbRegeln umgewandelt.
Delphi-Quellcode:
unit Unit2;

interface
...
  var
    TypNum: String;
    TypSonderZeichen: String;
    TypAlphaNum: String;
    AktRegel: TRegeln; // Record: Aktuelle Regel-Maske
    LtzRegel: TRegeln; // Record: Letzte geladene Regel
    LoadRegel: TDbRegeln; // Record: DbRegel, die geladen wurde
    SafeRegel: TDbRegeln; // Record: DbRegel, die zum speichern überprüft wurde
Ich setzte mich jetzt mal an den Umbau zur class und werde dann hier auch mal noch das (hoffentlich) funktionierende Ergebnis für andere Hilfesuchenden posten.

Bis dahin, danke für die zahlreiche Hilfe!

PS: Ich kenne ja "Neue Frage neuer Thread", aber da es hier erwähnt wurde lass ich's mal hier stehen:
Zitat:
...schreib dir Setter für deine Record Felder und setze dort einen Breakpoint, dann solltest du sehen wer dir da deine Werte zurücksetzt.
- Wie setzte ich das z.B. für AktRegel.ProbenartNr um? Denn dieser ist Initial '0', bekommt aus LoadRegel in Unit3 den Wert aus der DB-Tabellenzeile '10'...AktRegel.ProbenartNr := IntToStr(LoadRegel.Probenart_Nr); ..., was auch mit dem Debugger verfolgbar ist (wenn ich mit der Maus über den Variablennamen gehe), und springt der Debugger zurück zu dem Aufrufer Unit1, ist der Wert AktRegel.ProbenartNr laut Debugger in allen Units wieder '0'.
Markus
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.288 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 27. Jul 2015, 10:16
Du brauchst keinen Setter. Setze einfach nachdem die Zuweisung im Debugger passiert ist einen Datenhaltepunkt auf AktRegel.ProbenartNr . Das geht über die Liste der Haltepunkte, der linke Button hat ein Dropdownmenü.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 27. Jul 2015, 10:17
Wenn du das komische Verhalten auf ein Beispiel minimieren kannst, können wir dir sicher auch leichter helfen.
Hinter dir gehts abwärts und vor dir steil bergauf ! (Wolfgang Ambros)
  Mit Zitat antworten Zitat
marfin777

Registriert seit: 23. Jul 2015
5 Beiträge
 
Delphi XE8 Professional
 
#9

AW: Record, der überschrieben wird, bekommt wieder Initialwerte

  Alt 27. Jul 2015, 12:40
Okay... erster Beitrag und schon wird's peinlich.

Bevor ich mir jetzt ne gute Ausrede überlege, fass ich mich kurz.
Ich hatte tatsächlich noch ein AktRegel : TRegeln in der Unit1 stehen, was das Verhalten komplett erklärt und baumina's Vermutung
Zitat:
Oder hat die Unit1 vielleicht versehentlich auch eine lokale Variable Namens AktRegel?
richtig war.

Entschuldigt bitte den Aufwand
Markus

Geändert von marfin777 (27. Jul 2015 um 12:46 Uhr)
  Mit Zitat antworten Zitat
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 10:51 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