Announcement

Collapse
No announcement yet.

Wie speichert man richtig in einer Datei ab?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Wie speichert man richtig in einer Datei ab?

    Hallo,<BR>
    ich habe ein Programm mit ca. 350 Editfeldern und ComboBoxen. Dazu noch mal 300 Checkboxen. Der Inhalt der Felder und Zustand der Checkboxen soll abspeicherbar sein. Dazu habe ich eine Variable (CFG) vom Typ record benutzt.

    type TConfig = record<BR>
    XXX:string[255];<BR>
    YYY:boolean;<BR>
    usw.<BR>
    end;

    var
    f1:file of TConfig;<BR>
    CFG:TConfig;

    In die Variable schreibe ich mit

    procedure WriteCFG;<BR>
    begin<BR>
    with CFG, FormMain do<BR>
    begin<BR>
    XXX:=EditXXX.Text;<BR>
    YYY:=CheckBoxYYY.Checked;<BR>
    usw.<BR>
    end;

    und speichere die Variable CFG in eine Datei mit

    AssignFile(f1, Dateiname);<BR>
    Rewrite(f1);<BR>
    Write(f1, CFG);<BR>
    CloseFile(f1);

    Die Datei öffne ich und lese die CFG Variable aus mit

    AssignFile(f1, FileName);<BR>
    Reset(f1);<BR>
    Read(f1, CFG);<BR>
    CloseFile(f1);

    Aus der Variable lese ich die Feldinhalte wieder in die Felder ein mit

    procedure ReadCFG;<BR>
    begin<BR>
    with CFG, FormMain do<BR>
    begin<BR>
    EditXXX.Text := XXX;<BR>
    EditYYY.Text := YYY;<BR>
    usw.

    Alles funktioniert auch fast. Aber ab 280 Felder wird nicht alles wieder zurückgeschrieben.

    Jetzt meine Frage:
    Gibt es da irgendeine Groessenbeschraenkung fuer die record Variable? Und speichert man sowas ueberhaupt in record Variablen ab? Ich will ja nicht mehrere Zustaende in einer Datei abspeichern wie in einer Datenbank, sondern nur einen Datensatz. Der naechste Datensatz soll in einer anderen Datei abgespeichert werden.

    Gruss Matthias
    <BR>

  • #2
    Hallo,

    ändere einmal Boolean in Bool oder mache aus dem Record einen Packed-Record.

    type TConfig=packed record
    xxx:String[255];
    ...
    end;

    Gruß
    Thoma

    Comment


    • #3
      Hallo,

      warum so kompliziert. Ein VCL-Formular ist in der Lage, mit einem <b>WriteComponent</b>-Aufruf den Zustand aller eingebetteten Client-Controls in eine Datei zu schreiben, so das beim nächsten Programmstart der Inhalt alle Controls über <b>ReadComponent</b> wieder aus dieser Datei eingelesen werden kann. Somit speichert das Programm alle Einträge im TEdit, TMemo und die Auswahl einer TCheckBox - nur um einige Beispiele zu nennen. Das könnte so aussehen:
      <pre>
      unit ReadComponentFrm;

      interface

      uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;

      type
      TForm1 = class(TForm)
      Edit1: TEdit;
      Edit2: TEdit;
      Edit3: TEdit;
      Memo1: TMemo;
      CheckBox1: TCheckBox;
      CheckBox2: TCheckBox;
      CheckBox3: TCheckBox;
      ButtonClose: TButton;
      procedure ButtonCloseClick(Sender: TObject);
      procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
      private
      { Private-Deklarationen }
      FFilename : String;
      public
      { Public-Deklarationen }
      constructor Create(aOwner: TComponent); override;
      end;

      var
      Form1: TForm1;

      implementation

      {$R *.DFM}

      constructor TForm1.Create(aOwner: TComponent);
      var
      fs: TFileStream;
      begin
      FFilename := ExtractFilePath(ParamStr(0)) + Classname + '.DAT';
      if FileExists(FFilename) then
      begin
      CreateNew(aOwner);
      fs:= TFileStream.Create(FFilename, fmOpenread or fmShareDenyWrite);
      try
      fs.ReadComponent(self);
      finally
      fs.free;
      end;
      end
      else
      inherited Create(aOwner);
      end;

      procedure TForm1.ButtonCloseClick(Sender: TObject);
      begin
      Close;
      end;

      procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
      var
      fs: TFilestream;
      begin
      fs:= TFilestream.Create(FFilename, fmCreate);
      try
      fs.WriteComponent(self);
      finally
      fs.free;
      end;
      end;

      end.

      </pre&gt

      Comment


      • #4
        Hi Matthias,<br>
        vielleicht hast du einen langen String (AnsiString = verkleideter Zeiger) in deinem Record. Dann würde ein "file of TConfig" nicht fehlerfrei funktionieren.<br>
        Ciao, Uli

        Comment


        • #5
          hallo,<BR>
          danke für die antworten an alle. packed-record oder bool hat nicht funktioniert und WriteComponent kann ich nicht benutzen, da die abgespeicherten daten der editfelder in einem zweiten programm in dbeditfeldern eingelesen werden. die datei soll die schnittstelle zwischen zwei programmen sein.<br>
          was ich gar nicht verstanden habe ist ein (AnsiString = verkleideter Zeiger). wie würde so ein fehler denn aussehen?<br>
          komisch ist nur, wenn ich alle zustände speichere und wieder laden will tritt der fehler auf. wenn ich aber speichere, das programm beende, neu starte und dann einlese, funktioniert es!

          gruss matthia

          Comment


          • #6
            Unter http://www.eldos.org/elpack/ gibt es im Komponentenpack (Kostenpflichtig) eine Komponente TElFormPersist (http://www.eldos.org/elpack/custom.html), mit welchem man bestimmen kann, welche Properties des Formulars bzw. der darauf liegenden Komponenten gespeichert werden soll. Evaluierungsversion zum testen ist vorhanden

            Comment


            • #7
              <i>was ich gar nicht verstanden habe ist ein (AnsiString = verkleideter Zeiger). wie würde so ein fehler denn aussehen?</i><br>
              Ich seh schon, ich hab mich wieder super verständlich ausgedrückt. :-)
              Was ich meinte, ist Folgendes: Wenn du in deinem Record irgendwo<pre>
              EinString: string;
              </pre>stehen hast (und nicht mit {$H-}/{$LONGSTRINGS OFF} arbeitest),
              dann werden beim Wegschreiben des Records nicht die Zeichen von EinString gespeichert,
              sondern nur ein Zeiger darauf. Beim Einlesen der Datei liest du dann ebendiesen
              Zeiger, der aber schon lang nicht mehr gültig ist. Das führt dazu, dass dein Programm
              abstürzt oder sich zumindest "komisch" verhält.
              <p>Uli

              Comment


              • #8
                oh gott, wo wird denn dieses {$H-}/{$LONGSTRINGS OFF} hingeschrieben oder benutzt? sowas habe ich ja noch gar nicht benutzt

                Comment


                • #9
                  Schau mal in der Delphi-Hilfe unter "String-Typen" nach. Da hast du die definitive Referenz. ;-)
                  <br>Uli

                  Comment


                  • #10
                    Hallo Leute,

                    wenn ich mich hier mit einklinken darf, würde ich diesbezüglich ein paar fragen stellen.

                    1. wohin werden denn die ausgelesen inhalte geschrieben? ich seh gar keinen save-dialog.

                    2. wäre es möglich diese art der speicherung in einer unit durchzuführen, die aber alle controls der units des projektes speichert?

                    to

                    Comment


                    • #11
                      schritt 1: ein programm soll die daten eines für kunden installierten rechners erfassen. der kundenrechner wird installiert und das programm ermittelt ip adresse, name, produktnummern, installierte software usw. was sich nicht automatisch ermitteln lässt, wird von hand in die felder geschrieben. da an diesem rechner keine verbindung zu einem drucker oder zu einer datenbank besteht, sollen die daten in eine datei geschrieben werden.<br>
                      schritt 2: ein zweites programm im netzwerk mit drucker usw. übernimmt die daten. die editkomponenten sind jetzt aber dbeditkomponenten. so sollen die ermittelten daten für die weiterverarbeitung wie listendruck, auswertung usw. in einer db gespeichert werden.

                      der save-und open-dialog ist in der unit vom hauptformular:

                      <PRE>
                      procedure TFormMain.MenuFileSaveClick(Sender: TObject);
                      begin
                      Config.WriteCFG;
                      if Dateiname = '' then
                      MenuFileSaveAsClick(Sender)
                      else
                      begin
                      AssignFile(f1, Dateiname);
                      Rewrite(f1);
                      Write(f1, CFG);
                      CloseFile(f1);
                      end;
                      end;
                      </PRE>
                      <PRE>
                      procedure TFormMain.MenuFileOpenClick(Sender: TObject);
                      begin
                      with OpenDialog do
                      if Execute then
                      begin
                      Dateiname := FileName;
                      FormMain.Caption := 'IA0001 - ' + Dateiname;
                      AssignFile(f1, FileName);
                      Reset(f1);
                      Read(f1, CFG);
                      Config.ReadCFG;
                      CloseFile(f1);
                      end;
                      end;
                      </PRE>

                      in der unit config soll die variable CFG geschrieben und wieder ausgelesen werden. (siehe ganz oben)

                      die zwei programme sind notwendig, da auf dem zu installierenden kundenrechner keine db läuft.

                      matthia

                      Comment

                      Working...
                      X