![]() |
Delphi-Version: 10 Seattle
Delphi Record in for-schleife
Hallo,
ich habe folgende Frage, suche bereits schon seit einiger Zeit, bin aber nicht fündig geworden. Ich möchte ein Rekord z.B. wie folgt: Type TtestRecord = record Test1 = String[10]; Test2 = String[20]; Test3 = String[50]; Test4 = String[50]; Weitere 20… End; Ich möchte diese in einem String zusammenführen um sie dann in einer Datenbank abzulegen. In einer for schleife muss ich jeden einzelnen mit Namen ansprechen z.B. For i = 0 to High(testRecord) do Begin Str := Str + testRecord[i].test1; Str := Str + testRecord[i].test2; Usw. End; Kann man hier nicht so etwas anwenden? For i = 0 to High(testRecord) do begin For n = 0 to testRecord_Feldanzahl do Begin Str := Str + testRecord[i][n]; End; Str := Str + sLineBreaker; End; Fertig? |
AW: Delphi Record in for-schleife
Da geht vllt. mit RTTI. System.RTTI -> TRTTIContext
|
AW: Delphi Record in for-schleife
Ich weiß nicht ob du dir mit deinen Shortstrings wirklich einen Gefallen tust, weil du könntest ja auch einfach ein String-Array nehmen.
Aber falls du das wirklich behalten willst kannst du deinem Record einen Indexer verpassen:
Delphi-Quellcode:
Dann kann man z.B. sagen
type
TTestRecord = record Test1: String[10]; Test2: String[20]; Test3: String[30]; private function getThings(index: Integer): String; public property Things[index: Integer]: String read getThings; default; end; { TTestRecord } function TTestRecord.getThings(index: Integer): String; begin case index of 0: Result := Test1; 1: Result := Test2; 2: Result := Test3; else Result := String.Empty; // oder EArgumentOutOfRangeException werfen end; end;
Delphi-Quellcode:
procedure p();
var test: TTestRecord; index: Integer; text: String; begin test.Test1 := 'Hallo'; test.Test2 := 'Welt'; test.Test3 := 'Delphi'; text := String.Empty; for index := 0 to Pred(3) do text := text + test[index]; WriteLn(text); readln; end; |
AW: Delphi Record in for-schleife
Kurz zusammengebastelt:
Delphi-Quellcode:
Dafür muss dein Record aber zu 100% aus ShortStrings bestehen.
uses
System.RTTI; type TTestRecord = record Test1: String[10]; Test2: String[20]; Test3: String[50]; Test4: String[50]; End; procedure TForm1.FormCreate(Sender: TObject); var testRec: TTestRecord; rtti: TRttiContext; typ: TRttiType; field: TRttiField; recAsString: AnsiString; begin testRec.Test1 := 'Hallo'; testRec.Test2 := 'Welt'; testRec.Test3 := 'und'; testRec.Test4 := 'so'; rtti := TRttiContext.Create; try typ := rtti.GetType(TypeInfo(TTestRecord)); recAsString:= ''; for field in typ.GetFields() do recAsString := recAsString + PShortString(NativeUInt(@testRec) + NativeUInt(field.Offset))^; ShowMessage(String(recAsString)); finally rtti.Free; end; end; |
AW: Delphi Record in for-schleife
Besten Dank an euch,
Der schöne Günther, da hast du vollkommen recht ich mache es mir nur komplizierter als es ist:) ich folge deinem Rat und benutze einfach ein String Array. |
AW: Delphi Record in for-schleife
Da Du mit den guten alten short-strings arbeitest ginge auch folgendes:
Code:
Allerdings hast Du das Längenbyte jedes Strings mit drin und die Linebreaks fehlen.
var s: ansistring;
size: word; size := sizeOf( ttestRecord ); SetLength( s, size ); move( testRecord.Test1[0], s[0], size ) |
AW: Delphi Record in for-schleife
Teste das mal. Das funktioniert nicht. (Aus mehreren Gründen)
|
AW: Delphi Record in for-schleife
Zu dem Record (als "Packed" definiert) benötigt man eine zweite Struktur zur Definition der Felder des Records, z. B. ein Array, bei dem jedes Element Typ und Länge eines Feldes angibt. Mit den Informationen kann man dann die Position eines Feldes im Record berechnen und die Daten per Move auslesen.
Nutze ich zum Handling mit Datensätzen von Datenbanken. |
AW: Delphi Record in for-schleife
Zitat:
|
AW: Delphi Record in for-schleife
Zitat:
Ich muss allerdings zugeben, mich in der vergangenen Viertelstunde das erste Mal mit RTTI 'beschäftigt' zu haben...:oops: |
AW: Delphi Record in for-schleife
Kann man nicht den kompletten Record (muss natürlich im packed Format sein) als Blob speichern?
Ist bestimmt nicht die eleganteste Art, aber müsste doch gehen oder? |
AW: Delphi Record in for-schleife
Auf jeden Fall kann man den Record in einem File speichern, wenn mann dieses vom Typ her richtig definiert
Code:
Var
Ausgabedatei : File of MyRecord |
AW: Delphi Record in for-schleife
Muss nicht packed sein, aber das Format muß zumindestens statisch sein, nicht dass es in einem späteren Compilevvorgang oder mit anderen Optionen plötzlich anders ausgerichtet ist.
Align gleich, die Typen gleich, also auch nicht 32 Bit und 64 Bit vergessen, usw. Und vor allem dürfen die Typen im Record keine Pointer enthalten, wie z.B. LongStrings (String/AnsiString/UnicodeString/...) Gut, bei
Delphi-Quellcode:
hast den Vorteil dass'de nicht casten musst und die Datei nur diesen Record enthalten kann, aber auch in einfachen Binärdateien und Streams kann man Records speichern, wobei man dort dann eben über einen Pointer @DeinRecord + SizeOf(DeinRecord) geht.
File of MyRecord
PS: Viele gehen weg von diesen alten Pascal-Proceduren, hin zu Objektorientiert, also z.B. Streams und Daten-Objekte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:28 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