![]() |
Anzahl der Felder in einem Record
Hallo zusammen,
gleich die Frage vorweg: Gibt es eine Routine, die die Anzahl der Felder in einem (packed) record zurück gibt? Hintergrund: Ich habe mehrere Records unterschiedlicher Größe, möchte aber nur eine Speicherroutine schreiben. Bsp.:
Delphi-Quellcode:
Interessant wäre eine erweiterte Version, die den Feldtyp erkennt und im Falle eines verschachtelten Records auch die Anzahl der Felder des "Unterrecords" bearbeitet/wiedergibt.
type
TRec1 = packed record Field1: integer; Field2: string; Field3: string; end; TRec2 = packed record Field1: integer; Field2: string; Field3: string; Field4: string; end; Bsp.:
Delphi-Quellcode:
Gruß, Carsten
type
TRec1a = packed record Field1: integer; Field2: string; Field3: string; end; TRec1b = packed record Field1: integer; Field2: string; end; TRec1 = packed record Field1: integer; Field2: TRec1a; Field3: TRec1b; Field4: string; end; TRec2 = packed record Field1: integer; Field2: string; Field3: string; Field4: string; end; |
Re: Anzahl der Felder in einem Record
Stichwort: Variante Records
Muss man den String nicht begrenzen? |
Re: Anzahl der Felder in einem Record
Frag doch die Größe ab. Macht Windows genauso.
Und pass auf mit deinen Strings. Das sind nur zeiger auf einen Speicherbereich. Du müsstest hier ShortStrings verwenden. |
Re: Anzahl der Felder in einem Record
Nur wenn du den Record als Speicherstück lesen/Schreiben/Speichern/laden willst musst du einen Festen String nehmen.
Wenn du eh jedes Feld von Hand speicherst nicht. |
Re: Anzahl der Felder in einem Record
Typen welche eine Initialisierung/Finalisierung benötigen dürfen im variaten Teil des Records nicht verwendet werden.
Ergo lassen sich diese Records nicht als vaianten record vereinen. ShortStrings würden aber gehe, da sie sowas nicht benötigen. Außerdem kann man programmseitig (ohne weiteres Feld, welches Angibt welche Variante rad genutzt wird) nicht feststellen (nja, nicht unbedingt mit Sicherheit) welcher Typ verwendet wird. Wieso nutzt du denn nicht nur Rec2? (es enthält, zumindestens vom Aufbau her, den Rec1) hier würde ich sagen, verwende Rec2 und speichere nur das, was von einem Standardwert abweichet (bei String z.B. <> '') |
Re: Anzahl der Felder in einem Record
Dann ist da noch die Frage: Ist die Lösung über Records soviel eleganter als die über Objekte?
Mit Objekten könntest du dafür sorgen das jedes sich selbst serialisiert/deserialisiert. |
Re: Anzahl der Felder in einem Record
Zitat:
Gruß, Carsten |
Re: Anzahl der Felder in einem Record
Benutze TRec2 im Programm und speichere deine Daten im XML-Format.
|
Re: Anzahl der Felder in einem Record
Zitat:
Es gibt ein sog. Masterrecord, dass viele Unterrecords hat. Diese Unterecords haben aber mitunter nicht nur Felder, sondern wiederum Unterecords (max. 4 Ebenen). Gruß, Carsten |
Re: Anzahl der Felder in einem Record
Welche Delphiversion nutzt du denn?
|
Re: Anzahl der Felder in einem Record
Zitat:
|
Re: Anzahl der Felder in einem Record
Properties im Varianten Teil sind leider auch nicht möglich, aber sowas wäre da schon möglich:
- intern alle nötigen Felder jedes Types erstellen - und nach Außen, dann jeweils pasend zu den Einzelrecords, die Properties auf diese Felder verteilen - hier könnte man auch Setter-/Gettermethoden verwenden, um z.B. noch einen Identifierer su beschreiben, welcher angibt, welche Version (welche Property-Gruppe) verwendet wurde
Delphi-Quellcode:
Type
MyRecord = Record Private iFeld1: Integer; iFeld2: String; iFeld3: String; iFeld4_1: String; iFeld4_2: Integer; Public Property Rec1_Feld1: Integer Read iFeld1 Write iFeld1; Property Rec1_Feld2: String Read iFeld2 Write iFeld2; Property Rec1_Feld3: String Read iFeld3 Write iFeld3; Property Rec2_Feld1: Integer Read iFeld1 Write iFeld1; Property Rec2_Feld2: String Read iFeld2 Write iFeld2; Property Rec2_Feld3: String Read iFeld3 Write iFeld3; Property Rec2_Feld4: String Read iFeld4_1 Write iFeld4_1; Property Rec3_Feld1: Integer Read iFeld1 Write iFeld1; Property Rec3_Feld2: String Read iFeld2 Write iFeld2; Property Rec3_Feld3: Integer Read iFeld4_2 Write iFeld4_2; End;
Delphi-Quellcode:
beim Speichern dann entweder über iType die Speichermethode wählen, alles speichern oder alles abweichend von einem Defaultwert speichern.
Type
MyRecord = Record Private iType: Integer; // oder 'nen SET iFeld1: Integer; iFeld2: String; iFeld3: String; iFeld4_1: String; iFeld4_2: Integer; Public Property Rec1_Feld1: Integer Read iFeld1 Write SetRec1Feld1; Property Rec1_Feld2: String Read iFeld2 Write SetRec1Feld2; |
Re: Anzahl der Felder in einem Record
Was spricht eigentlich gegen RTTI? Zumindest Recordgröße und Position von Strings (und anderen finalisierungsbedürftigen Typen) ist abrufbar.
|
Re: Anzahl der Felder in einem Record
Warum so kompliziert!
Delphi-Quellcode:
Und umgekehrt einlesen! Fertig!
var
MyRec : byte; begin ... MyRec := 1; // oder 2 3 Blockwrite(Datei,MyRec,1); Case MyRec of 1 : Blockwrite(Datei,Rec1,sizeof(Rec1)); 2 : Blockwrite(Datei,Rec2,sizeof(Rec2)); 3 : Blockwrite(Datei,Rec3,sizeof(Rec3)); end; // of case ... end; Mavarik :coder: |
Re: Anzahl der Felder in einem Record
Zitat:
Ich könnte ja jetzt (umständlicher Weg) für jedes Record eine eigene Speicherroutine schreiben, ich hätte hingegen aber (einfacher Weg[?]) eine Speicherroutine, die zunächst (auch im rekursiven Aufruf) die Feldtypen der Records (und Unterrecords) ermittelt, daraus Strings bastelt und diese Strings dann speichern. Viel "lustiger" wird es ja bei diesem Konstrukt:
Delphi-Quellcode:
Was ja - zumindest schon im Ansatz - klappt, ist das
TKontaktartenEingang = packed record
Kontaktart: word; case Word of EINGANG_KONTAKT_SCHLIESSER, EINGANG_KONTAKT_OEFFNER : ( Dummy: byte; Ansprechzeit_Digital: word; ); EINGANG_KONTAKT_ANALOG_0_10V, EINGANG_KONTAKT_ANALOG_0_20MA, EINGANG_KONTAKT_ANALOG_4_20MA : ( KonfigID : word; Ansprechzeit_Analog : word; Sensorausfall : boolean; MinValue : word; MaxValue : word; Schwellwert1 : word; Schwellwert2 : word; Invert : boolean; ); end; TEingang = packed record Kennung : string; Kontaktart: TKontaktartenEingang; end; ![]() Allerdings fehlt mir nach wie vor eine Routine oder ggf. eine Schleife ala ForEach in PHP zum zählen, die mir die Anzahl der Recordfelder zurück gibt und bei Unterrecords meckert leider der Compiler "Inkompatible Typen: Variant und {Unterrecord}". Gruß, Carsten |
Re: Anzahl der Felder in einem Record
Zitat:
Waraum dann so Heckmeck mit Varianten Records und vielen verschiedenen Typen? Grüsse Mavarik |
Re: Anzahl der Felder in einem Record
Delphi-Quellcode:
// statt
Kontaktart: word; case Word of // geht auch (ist eventuell auch besser zu erkennen, wofür "Kontaktart" genutzt wird) case Kontaktart: Word of Zitat:
@Carsten1234: vielleicht wäre es an dieser Stelle dann doch nicht schlecht, wenn du statt Records Klassen verwendest? Zitat:
da kannst doch ganz leicht, beim Speichern, über Kontaktart auswählen welche Teil gespeichert werden muß ... und beim Laden dann andersrum |
Re: Anzahl der Felder in einem Record
Zitat:
Zitat:
Gruß, Carsten |
Re: Anzahl der Felder in einem Record
ups ... stimmt, mein natürlich dich (da hat sich wohl ein copy&paste verlaufen :oops: )
|
Re: Anzahl der Felder in einem Record
Zitat:
Stelle Dir (abstraktes Bsp.) ein intelligentes Auto vor. Dieses Auto schließt Du an Deinen PC an und kannst dessen Setup auslesen als da wären Farbe, Reifen (Typ, Größe), Motor. Das Auto ist ferner so intelligent, dass Du ihm auch ein geändertes Setup zukommen lassen kannst. Nun könnte sich der Reifentyp je nach Jahreszeit ändern. Das könnte dann so aussehen:
Delphi-Quellcode:
Das Auto stellt Dir die Infos als CSV-Datei zur Verfügung, diese Infos sollen jedoch auch als ganzes "Paket" auf HDD gespeichert werden können. Ferner kannst Du dem Auto aber auch über einem sog. Teilsetup (in CVS-Form) sagen, dass es nun keine Sommereifen mehr hat, sondern Winterreifen. Es muss also nicht das komplette Record "TAuto" geschickt werden, es reicht das Record "Reifen" zu schicken.
TReifentyp = packed record
case Jahreszeit: byte of Sommerzeit: ( Breite_Sommer : word; Querschnitt_Sommer : word; Felgengroesse_Sommer: word; Index_Sommer : word; Hersteller_Sommer : string; ); Winterzeit: ( Breite_Winter : word; Querschnitt_Winter : word; Felgengroesse_Winter: word; Index_Winter : word; Hersteller_Winter : string; ); end; TMotortypen = packed record case Motortyp: byte of Benziner: ( KW_Benziner : word; Hubraum_Benziner: word; ) Diesel: ( KW_Diesel : word; Hubraum_Diesel: word; ) end; TAuto = packed record Farbe : string; Reifen : TReifenTyp; Motor : TMotortypen; Kennzeichen: string; Land : string; Bemerkungen: array[1..1024] of char; end; Wieder bezogen auf mein Problem wäre es nun ganz schön, wenn es zur Konvertierung Record => CVS und Speicherung des Teilsetups nur eine Routine geben würde, der einfach nur das entsprechende (Teil-)Record übergeben wird. Jetzt kann man natürlich die Zusatzfrage stellen, warum man nicht vor dem Speichern auf HDD erst nochmal das aktuelle Komplettsetup ausliest. Nun, im Record "TAuto" gibt es weitere Zusatzinfos, die das Auto nicht kennt wie sein Kennzeichen, das Land, in dem es zugelassen ist und Bemerkungen zum Auto ("Heckklappe rostet" oder so). Diese Informationen braucht das Auto auch nicht, sie sollen aber zur Verfügung stehen, wenn das Setup von HDD ins Programm geladen wird. Nun etwas klarer? Gruß, Carsten |
Re: Anzahl der Felder in einem Record
Zitat:
Tja, umschreiben, viel, viel Arbeit... |
Re: Anzahl der Felder in einem Record
Zitat:
Dazu hatte ich mal was in die Codelib gesetzt: ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:41 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-2025 by Thomas Breitkreuz