AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Record laden

Ein Thema von grader · begonnen am 25. Mär 2007 · letzter Beitrag vom 28. Mär 2007
Antwort Antwort
Seite 2 von 3     12 3      
grader

Registriert seit: 5. Mär 2007
19 Beiträge
 
Delphi 2005 Personal
 
#11

Re: Record laden

  Alt 26. Mär 2007, 14:05
Hallo!

Danke euch erstmal für eure Hilfe! Jetzt sieht es so aus:

Delphi-Quellcode:
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;
und


Delphi-Quellcode:
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;
Jetzt markiert er folgendes rot und sagt "variable required":

Stream.Write(PChar(T[I].T), Len); Dieses Tut habe ich übrigens verwendet..
Und da steht das mit dem "^" drin und so geht es auch zu kompilieren geht nur net

Gruß
Stefan

Edit:

hab jetzt noch das hier gefunden, was ich vielleicht später mal probieren werde:

klick

Jetzt hab ich aber erstmal andere Sorgen, morgen letzte Kursarbeit in Physik
the grader
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#12

Re: Record laden

  Alt 26. Mär 2007, 14:50
Dann halt so?
Stream.Write(T[I].B[1], Len); Aber wie schon mehrmals gefragt ... wie sieht denn die Definition deines Records aus?
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
grader

Registriert seit: 5. Mär 2007
19 Beiträge
 
Delphi 2005 Personal
 
#13

Re: Record laden

  Alt 26. Mär 2007, 15:00
Delphi-Quellcode:
type
  TDatum = record
  T,M,J: word;
  Zh,Zm,B,O,T1,T2,T3,T4,P,N: String;
end;
und

Delphi-Quellcode:
var
  T: array of TDatum;
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
the grader
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#14

Re: Record laden

  Alt 26. Mär 2007, 15:38
müßte stimmen
Delphi-Quellcode:
// 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;
Stream.Read/Write wollen ja einen Var/Const-Parameter, welcher auf den Stringinhalt zeigt und dieser beginnt beim 1. Zeichen.


Anders gesagt ... die Implementation von Stream.Read/Write ist sch***


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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
grader

Registriert seit: 5. Mär 2007
19 Beiträge
 
Delphi 2005 Personal
 
#15

Re: Record laden

  Alt 26. Mär 2007, 15:42
Du warst schneller, werds gleich mal probieren!
the grader
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.858 Beiträge
 
Delphi 11 Alexandria
 
#16

Re: Record laden

  Alt 26. Mär 2007, 16:07
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
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
grader

Registriert seit: 5. Mär 2007
19 Beiträge
 
Delphi 2005 Personal
 
#17

Re: Record laden

  Alt 26. Mär 2007, 16:12
Boah habs jetzt probiert und Ernüchterung folgte zugleich.. Ging wieder nicht

Hab aber auch rausgefunden warum:

for I := 0 to Length(T) - 1 do 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

@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
the grader
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#18

Re: Record laden

  Alt 26. Mär 2007, 16:40
Stream.Read/.Write sind doch bei dir so definiert?
Delphi-Quellcode:
Read(var Buffer; Count: Longint): Longint;
Write(const Buffer; Count: Longint): Longint;
Also dann sollte es doch funktionieren?

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:
// 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));
Bei 'nen packed Array (ebenfalls mit ShortStrings) müßte es auch so gehn:
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));
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
grader

Registriert seit: 5. Mär 2007
19 Beiträge
 
Delphi 2005 Personal
 
#19

Re: Record laden

  Alt 26. Mär 2007, 16:57
ööhm ich glaube nicht aber ich weiß auch grad net wie und wo

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..
Angehängte Dateien
Dateityp: rar project2_268.rar (35,7 KB, 7x aufgerufen)
the grader
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.858 Beiträge
 
Delphi 11 Alexandria
 
#20

Re: Record laden

  Alt 26. Mär 2007, 17:33
Hallo grader,

Zitat von himitsu:
strLaenge = maximale StringLänge (mehr geht dann nicht rein und soviel wird auch immer gespeichert, selbt wenn weniger drin ist)
Das sollte aber bei den heutigen Festplatten keine Problem sein.


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
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 22:34 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