![]() |
Re: Record laden
Hallo!
Danke euch erstmal für eure Hilfe! Jetzt sieht es so aus:
Delphi-Quellcode:
und
procedure TForm1.saverec;
var Stream: TStream; I: integer; Len: Longint; begin Stream := TFileStream.Create('c:\TMData.dat', fmCreate); try Len := Length(T); Stream.Write(Len, SizeOf(Len)); for I := 0 to Length(T) - 1 do begin Len := Length(IntToStr(T[I].T)); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].T), Len); Len := Length(IntToStr(T[I].M)); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].M), Len); Len := Length(IntToStr(T[I].J)); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].J), Len); Len := Length(T[I].Zh); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].Zh), Len); Len := Length(T[I].Zm); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].Zm), Len); Len := Length(T[I].B); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].B), Len); Len := Length(T[I].T1); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].T1), Len); Len := Length(T[I].T2); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].T2), Len); Len := Length(T[I].T3); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].T3), Len); Len := Length(T[I].T4); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].T4), Len); Len := Length(T[I].P); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].P), Len); Len := Length(T[I].N); Stream.Write(Len, SizeOf(Len)); Stream.Write(PChar(T[I].N), Len); end; finally Stream.Free; end; end;
Delphi-Quellcode:
Jetzt markiert er folgendes rot und sagt "variable required":
procedure TForm1.loadrec;
var Stream: TStream; I: integer; Len: LongInt; begin Stream := TFileStream.Create('c:\TMData.dat', fmOpenRead); try Stream.Read(Len, SizeOf(Len)); SetLength(T, Len); for I := 0 to Len - 1 do begin {Stream.Read(Len, SizeOf(Len)); SetLength(T[I].T, Len); Stream.Read(PChar(T[I].T), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].M, Len); Stream.Read(PChar(T[I].M), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].J, Len); Stream.Read(PChar(T[I].J), Len);} Stream.Read(Len, SizeOf(Len)); SetLength(T[I].Zh, Len); Stream.Read(PChar(T[I].Zh), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].Zm, Len); Stream.Read(PChar(T[I].Zm), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].B, Len); Stream.Read(PChar(T[I].B), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].T1, Len); Stream.Read(PChar(T[I].T1), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].T2, Len); Stream.Read(PChar(T[I].T2), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].T3, Len); Stream.Read(PChar(T[I].T3), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].T4, Len); Stream.Read(PChar(T[I].T4), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].P, Len); Stream.Read(PChar(T[I].P), Len); Stream.Read(Len, SizeOf(Len)); SetLength(T[I].N, Len); Stream.Read(PChar(T[I].N), Len); end; finally Stream.Free; end; end;
Delphi-Quellcode:
Stream.Write(PChar(T[I].T), Len);
![]() Und da steht das mit dem "^" drin und so geht es auch zu kompilieren geht nur net :gruebel: Gruß Stefan Edit: hab jetzt noch das hier gefunden, was ich vielleicht später mal probieren werde: ![]() Jetzt hab ich aber erstmal andere Sorgen, morgen letzte Kursarbeit in Physik :roll: |
Re: Record laden
Dann halt so?
Delphi-Quellcode:
Aber wie schon mehrmals gefragt ... wie sieht denn die Definition deines Records aus?
Stream.Write(T[I].B[1], Len);
|
Re: Record laden
Delphi-Quellcode:
und
type
TDatum = record T,M,J: word; Zh,Zm,B,O,T1,T2,T3,T4,P,N: String; end;
Delphi-Quellcode:
Achso wenn ich das aus deinem letzten Post nehme, sagt er nur Array type required! Außerdem verstehe ich nicht ganz was das bewirken soll :gruebel:
var
T: array of TDatum; |
Re: Record laden
müßte stimmen
Delphi-Quellcode:
Stream.Read/Write wollen ja einen Var/Const-Parameter, welcher auf den Stringinhalt zeigt und dieser beginnt beim 1. Zeichen.
// Schreiben
Len := Length(T); Stream.Write(Len, SizeOf(Len)); for I := 0 to Length(T) - 1 do begin Stream.Write(T[I].T, SizeOf(Word) * 3); // .T, .M und .J zusammen Len := Length(T[I].Zh); Stream.Write(Len, SizeOf(Len)); If Len > 0 Then Stream.Write(T[I].Zh[1], Len); Len := Length(T[I].Zm); Stream.Write(Len, SizeOf(Len)); If Len > 0 Then Stream.Write(T[I].Zm[1], Len); Len := Length(T[I].B); Stream.Write(Len, SizeOf(Len)); If Len > 0 Then Stream.Write(T[I].B[1], Len); ... Len := Length(T[I].N); Stream.Write(Len, SizeOf(Len)); If Len > 0 Then Stream.Write(T[I].N[1], Len); end; // Lesen Stream.Read(Len, SizeOf(Len)); SetLength(T, Len); for I := 0 to Length(T) - 1 do begin Stream.Read(T[I].T, SizeOf(Word) * 3); // .T, .M und .J zusammen Stream.Read(Len, SizeOf(Len)); SetLength(T[I].Zh, Len); If Len > 0 Then Stream.Read(T[I].Zh[1], Len); ... Stream.Read(Len, SizeOf(Len)); SetLength(T[I].N, Len); If Len > 0 Then Stream.Read(T[I].N[1], Len); end; Anders gesagt ... die Implementation von Stream.Read/Write ist sch*** :angel2: Ach ja, da der Zugriff auf [1] nicht möglich ist, wenn der String leer ist, muß halt nich mit IF dieser Zustand abgefangen werden. Wenn du garantieren kannst, daß die strings immer mit mindestens einem Zeichen gefüllt sind, dann kannst du natürlich die IF-Abfragen weglassen und direkt Schreiben/Lesen. |
Re: Record laden
Du warst schneller, werds gleich mal probieren!
|
Re: Record laden
Hallo grader,
schau dir mal das Tut. ‚Records in einem FileStream speichern’ an. Ich würde nicht lange Strings verwenden, sondern kurze Strings, wenn das Möglich ist. Bei langen String muss immer die Länge der Strings mit verwaltet werden, dies ist sehr aufwendig. Bei kurzen Strings ist der Record immmer gleich groß. statt:
Delphi-Quellcode:
type
TDatum = record T,M,J: word; Zh,Zm,B,O,T1,T2,T3,T4,P,N: String; end;
Delphi-Quellcode:
const strLaenge= 20; // Strings sind 20 Zeichen lang.
type TDatum = packed record T: Word; M: Word; J: Word; Zh: string[strLaenge]; Zm: string[strLaenge]; B: string[strLaenge]; O: string[strLaenge]; T1: string[strLaenge]; T2: string[strLaenge]; T3: string[strLaenge]; T4: string[strLaenge]; P: string[strLaenge]; N: string[strLaenge]; end; Bis bald Chemiker |
Re: Record laden
Boah habs jetzt probiert und Ernüchterung folgte zugleich.. Ging wieder nicht :wall:
Hab aber auch rausgefunden warum:
Delphi-Quellcode:
Hab Length(T) testweise durch eine Zahl ersetzt und voila es funktioniert! Dann hab ich mir Length(T) mal ausgeben lassen und egal wie viele Einträge vorhanden sind er gibt immer nur "1" aus! Es nimmt halt kein Ende, aber ich glaube jetzt isses nicht mehr weit ;)
for I := 0 to Length(T) - 1 do
@Chemiker Ja das hatte ich auch schon mal gelesen, aber irgendwie hatte ich dann an anderen Stellen Probleme mit den ShortStrings zu arbeiten.. Is aber auch schon ein Stück her, werds dann nochmal probieren, THX :) |
Re: Record laden
Stream.Read/.Write sind doch bei dir so definiert?
Delphi-Quellcode:
Also dann sollte es doch funktionieren? :gruebel:
Read(var Buffer; Count: Longint): Longint;
Write(const Buffer; Count: Longint): Longint; Hast du mal ein Testprogramm zur Verfügung? Jedenfalls zu Chemiker's Vorschlag: strLaenge = maximale StringLänge (mehr geht dann nicht rein und soviel wird auch immer gespeichert, selbt wenn weniger drin ist)
Delphi-Quellcode:
Bei 'nen packed Array (ebenfalls mit ShortStrings) müßte es auch so gehn:
// Schreiben
Len := Length(T); Stream.Write(Len, SizeOf(Len)); for i := 0 to Length(T) - 1 do Stream.Write(T[i], SizeOf(TDatum)); // Lesen Stream.Read(Len, SizeOf(Len)); SetLength(T, Len); for i := 0 to Length(T) - 1 do Stream.Read(T[i], SizeOf(TDatum));
Delphi-Quellcode:
// Schreiben
Len := Length(T); Stream.Write(Len, SizeOf(Len)); Stream.Write(T[0], SizeOf(TDatum) * Length(T)); // Lesen Stream.Read(Len, SizeOf(Len)); SetLength(T, Len); Stream.Read(T[0], SizeOf(TDatum) * Length(T)); |
Re: Record laden
Liste der Anhänge anzeigen (Anzahl: 1)
ööhm ich glaube nicht aber ich weiß auch grad net wie und wo :angel2:
Hab dir mein Prog mal in den Anhang geladen, aber ohne die .EXE.. Und bitte nicht wundern, da sind 6 Units, aber ich benutze nur eine, wenn ich die anderen aber lösche gehts net mehr.. |
Re: Record laden
Hallo grader,
Zitat:
Vieleicht hilft dir das weiter:
Delphi-Quellcode:
unit FileStreamHilfeUnit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Edit7: TEdit; Edit8: TEdit; Edit9: TEdit; Edit10: TEdit; Edit11: TEdit; Edit12: TEdit; Edit13: TEdit; Edit14: TEdit; Edit15: TEdit; Edit16: TEdit; Edit17: TEdit; Edit18: TEdit; Edit19: TEdit; Edit20: TEdit; Edit21: TEdit; Edit22: TEdit; Edit23: TEdit; Edit24: TEdit; Edit25: TEdit; Edit26: TEdit; Button1: TButton; Button2: TButton; DatenSatzNr: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; const strLaenge= 20; // Strings sind 20 Zeichen lang. type TDatum = packed record T: Word; M: Word; J: Word; Zh: string[strLaenge]; Zm: string[strLaenge]; B: string[strLaenge]; O: string[strLaenge]; T1: string[strLaenge]; T2: string[strLaenge]; T3: string[strLaenge]; T4: string[strLaenge]; P: string[strLaenge]; N: string[strLaenge]; end; var Form1: TForm1; implementation {$R *.dfm} function Stream_MW_Rec_Anhaengen (f: TFileStream; MWRec: TDatum): boolean; begin try f.Position:=0; f.Seek(0, soFromEnd); // Datenzeiger auf das Ende des Streams setzen. f.WriteBuffer(MWRec, SizeOf(TDatum)); result:= TRUE; except ShowMessage('Es ist beim Datensatz speichern ein Fehler aufgetreten!'); result:= FALSE; end; end; function Stream_MW_Rec_Lesen (f: TFileStream; var MWRec: TDatum; DatensatzNr: integer): boolean; begin try f.Position:=0; // An dieser Stelle wird der Datei-Zeiger auf den zu lesenden // Datensatz gestellt. Durch -soFromBeginning- wird der Dateizeiger // auf den Anfang gesellt. f.Seek((SizeOf(TDatum)*DatensatzNr), soFromBeginning); f.ReadBuffer(MWRec, SizeOf(TDatum)); result:= TRUE; except ShowMessage('Es ist beim Datensatz lesen ein Fehler aufgetreten!'); result:= FALSE; end; end; function Stream_MW_Rec_DatenSatzAnzahl (f: TFileStream; MWRec: TDatum): integer; begin result:= 0; if f.Size>0 then begin // Berechnung: Gesamte Stream-Lämge / TMW_Stream_Rec // Das ergibt die Datensatz-Anzahl result:= trunc(f.Size/SizeOf(TDatum)); end; end; function Stream_oeffnen (var f: TFileStream ;const DateiName: string): boolean; begin result:= TRUE; try {-- FileStream zum Lesen u. Schreiben uneingeschränkt öffnen -----------} f:= TFileStream.Create(DateiName, fmOpenReadWrite or fmShareDenyNone) except try { FileStream neu anlegen, tritt hier ein Fehler auf so wird das Prg. ab- } { gebrochen und zur der aufrufende Routine zurückgesprungen. } f:= TFileStream.Create(DateiName, fmCreate or fmShareDenyNone); except ShowMessage('Fehler beim Erzeugen der Datei:'+#13+DateiName); Exit; // Zur aufrufenden Routine zurück. end; result:= FALSE; end; end; procedure TForm1.Button1Click(Sender: TObject); var f: TFileStream; TDatum_Rec: TDatum; begin with TDatum_Rec do begin T:= strtoint(Edit1.Text); M:= strtoint(Edit2.Text); J:= strtoint(Edit3.Text); Zh:= Edit4.Text; Zm:= Edit5.Text; B:= Edit6.Text; O:= Edit7.Text; T1:= Edit8.Text; T2:= Edit8.Text; T3:= Edit9.Text; T4:= Edit10.Text; P:= Edit11.Text; N:= Edit12.Text; end; Stream_oeffnen (f ,'f:\TMData.dat'); Stream_MW_Rec_Anhaengen (f, TDatum_Rec); f.Free; end; procedure TForm1.Button2Click(Sender: TObject); var f: TFileStream; TDatum_Rec: TDatum; begin Stream_oeffnen (f ,'c:\TMData.dat'); Stream_MW_Rec_Lesen (f, TDatum_Rec, strtoint(DatensatzNr.Text)-1); with TDatum_Rec do begin Edit14.Text:= inttostr(T); Edit15.Text:= inttostr(M); Edit16.Text:= inttostr(J); Edit17.Text:=Zh; Edit18.Text:=Zm; Edit19.Text:=B; Edit19.Text:=O; Edit20.Text:=T1; Edit21.Text:=T2; Edit22.Text:=T3; Edit23.Text:=T4; Edit24.Text:=P; Edit25.Text:=N; end; end; end. Bis bald Chemiker |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:56 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