Datenbank, Daten sollen gespeichert werden

Hallo
nochmal ne Frage und zwar möchte ich mit Delphi eine Datenbankprogramm schreiben.
Die Daten sind in records abgespeichert und werden in einer StringGrid ausgegeben. Jetzt hab ich die Frage, wie ich das machen kann, dass die Daten gespeichert bleiben. Also wenn das Programm beendet wird oder Windows runtergefahren wird, dass ich die Datensätze immer noch habe.
Danke euch
MfG Pefi

Hallo,

also da ist schon mehr info nötig!

Was für ein Delphi benutzt du?

Welche Datenbank benutzt du?

Warum ein StringGrid und kein DataGrid?

etc.

Gruss, Niels

Hallo Pefi,
Wie unten schon angemerkt, wären genauere Infos hilfreich, sind aber in deinem Fall nicht nötig, wenn man davon ausgehen darf, dass du eine sehr einfache Lösung für dein Problem suchst.

Sagen wir, deine Daten befinden sich in einem Record TDaten. Liegen nun die Datensätze als Array vor (Array[] of TDaten) oder als verkettete Liste (mit Zeigern und so) ? Ich gehe jetzt der Einfachheit halber mal davon aus, du hast n Datensätze in einem Array Daten = Array[1…n] of TDaten.

Unten folgen ein paar Zeilen Code mit zwei Prozeduren, die dir das Prinzip zeigen sollen, wie du die Daten in eine Datei (zB. auf der Festplate) schreiben kannst (zB beim Beenden des Programms) (SaveToFile) und wieder öffnen kannst (zB bei Start des Programms) (LoadFromFile):

Const
 n = ... // Anzahl Datensätze

Type 
 TDaten = Record ... // deine Record-Struktur 
 TListe = Array[1..n] // Liste (Array) mit den Datensätzen

Procedure SaveToFile(Dateiname:String);
Var 
 F: File of TListe; // typisierte Datei
 i: integer;
begin
 AssignFile(F,Dateiname); 
 Rewrite(F);
 for i := 1 to n do Write(F,Liste[i]);
end;

Procedure LoadFromFile(Dateiname:String);
Var 
 F: File of TListe; // typisierte Datei
 i: integer;
begin
 AssignFile(F,Dateiname); 
 if FileExists(F) then
 begin
 ReSet(F);
 for i := 1 to n do Read(F,Liste[i]);
 end;
end;

Du findest weitere Hinweise in der Hilfe unter „AssignFile“.

Es gibt viele weitere Wege, die zum Ziel führen, wobei ich glaube, daß dies hier für dich der einfachste ist.

Wenn du ein dynamisches Array hast, weißt du beim Einlesen ja nicht, wie groß n ist, dann kannst du lesen, bis das Dateiende erreicht ist:

Procedure LoadFromFile(Dateiname:String);
Var 
 F: File of TListe; 
begin
 AssignFile(F,Dateiname); 
 if FileExists(F) then
 begin
 ReSet(F);
 n := 0;
 While not eof(F) do 
 begin
 inc(n);
 Read(F,Daten[n]);
 end;
 end;
end;

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hey, super!!
Wirklich. Ich wserds noch ausprobieren müssen (hab aber heute keine Zeit mehr dafür).
Aber nochmal, wirklich spitze.
Danke
Pefi

Fehlermeldungen en masse
Hi Jochen,
also ich hab die zwei Prozeduren in mein Program eingefügt. Es läuft aber nicht wie gewollt.
Mein array heisst Person[0…10]. Und ist vom Type pers_typ. pers_typ enthält Elemente wie Vorname, Name etc. die also mit z.B. Person[1].Name angesprochen werden.
Meine Frage ist zuerst mal bezüglich diser Datei: Muss ich die nicht zuerst erstellen diese Datei. Und woher weiss das Program, in welchem Ordner die ist?
Meine „Laden Prozedur“ lautet:

PROCEDURE LoadFromFile(var Dateiname : string);
var F: File of Person[0…10]; // Fehlermeldung: Konstante oder Typenbezeichnung erwartet
i: integer;
Begin
AssignFile(F,Dateiname);
if FileExists(F) then // Inkompatible Typen: ‚string‘ und ‚text‘
begin
ReSet(F);
for i:=0 to 10 do Read(F,Person[i]);
end;
End;

Die „Speichern Prozedur“:

PROCEDURE SaveToFile(var Dateiname : String);
var F: File of Person[0…10]; // Fehlermeldung: Konstante oder Typenbezeichnung erwartet
i: integer;
Begin
AssignFile(F,Dateiname);
Rewrite(F);
for i:=0 to 10 do Write(F,Person[i]);
End;

Allerdings muss ich dazu sagen, dass alle anderen Prozeduren, also die Ausgabe Prozedur, Sortieren Prozedur etc. zunächst oben deklariert hab und dann der Prozeduren Kopf z.B. TForm1.Ausgabe(var Person: array of pers_typ)
Und bei diesen Prozeduren mach ich das ja ohne diese Deklaration am Anfang und lass ja auch das TForm1 weg. Liegt es daran?

Ausserdem hab ich diese zwei Prozeduren, die die Speicher und Laden Prozeduren aufrufen.

procedure TForm1.BtnLadenClick(Sender: TObject);
begin
LoadFromFile(Dateiname); // Fehlermeldung: Undefinierter Bezeichner: ‚Dateiname‘
end;

procedure TForm1.BtnSpeichernClick(Sender: TObject);
begin
SaveToFile(Dateiname); // Fehlermeldung: Undefinierter Bezeichner: ‚Dateiname‘
end;

Ich denke mal, dass du in deinem Entry bei wer-weiss-was.de mit Dateiname nicht Dateiname selbst sondern eine adäquate Bezeichnung für diese Datei gemeint hast.
Naja, ich hoffe, dass die das weiterhilft. Die Delphi-Hilfe war zumindest nicht sehr hilfreich

Hey vielen Dank, dass du dir die Mühe machst. Ich bin halt nicht wirklich der Checker bzgl. Delphi.
Oh, und bevor ichs vergess. Ich programier noch mit Delphi 4, wird aber wohl (hoffentlich) nichts ausmachen.
Vielen vielen Dank

Pefi

Hi,

das ist alles in der Online-Hilfe dokumentiert!

es muß heißen:

var F: File of pers_typ;

if FileExists(Dateiname) then

Allerdings muss ich dazu sagen, dass alle anderen Prozeduren,
also die Ausgabe Prozedur, Sortieren Prozedur etc. zunächst
oben deklariert hab und dann der Prozeduren Kopf z.B.
TForm1.Ausgabe(var Person: array of pers_typ)
Und bei diesen Prozeduren mach ich das ja ohne diese
Deklaration am Anfang und lass ja auch das TForm1 weg. Liegt
es daran?

Nein, diese Prozeduren hast du als Methoden von TForm1 deklariert. Das geht auch. Viele Wege führen eben nach Rom.

Ich denke mal, dass du in deinem Entry bei wer-weiss-was.de
mit Dateiname nicht Dateiname selbst sondern eine adäquate
Bezeichnung für diese Datei gemeint hast.

exakt!

Oh, und bevor ichs vergess. Ich programier noch mit Delphi 4,
wird aber wohl (hoffentlich) nichts ausmachen.

Mein Delphi 3 macht Probleme mit typisierten Dateien, wenn der Record Strings enthält. Das läßt sich vermeiden, wenn du bei deinem pers_typ statt „String“ zB. Array[0…100] of Char angibst.

Vielen vielen Dank

Keine Ursache.
Jochen