Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi EDIT Inhalte in Datei abspeichern und wieder laden (https://www.delphipraxis.net/106090-edit-inhalte-datei-abspeichern-und-wieder-laden.html)

Andi44 5. Jan 2008 11:49


EDIT Inhalte in Datei abspeichern und wieder laden
 
Hallo Forum!

Ich habe ein kleines Programm geschrieben, dass nur aus einer Form besteht, dieses Programm rechnet die Theoertische Geschwindigkeit von Propeller getriebenen booten aus.

Es sind also ein paar EDIT Felder vorhanden in denen ich Zahlen eingeben muss, die in Variablen gespeichert werden.

- Drehzahl - , z.B. 4600
- Untersetzung , z.b. 1.75
- Steigung - z.b. 17

daraus errechnet er dann eine theoretische Geschwindigkeit auf Knopfdruck.

Nun möchte ich aber, damit es komfortabler wird, dass der Benutzer diese Inhalte als Datei abspeichern kann und später wieder laden kann um mit den Daten zu rechnen. ( es gibt ja viele verschiedenen Motoren mit verschiedenen drehzahlen , untersetzungen)

Das stelle ich mir so vor, dass ich einen Menüpunkt " abspeichern " in meine Form erstelle und dann soll ein Speichern Dialog erscheinen, wo ich dann in den Ordner springen kann, Dateinamen eingeben kann und schliesslich abspeichere.

Ausserdem möchte ich dann in meinem Menü einen Punkt " daten laden " erstellen, wo dann wieder ein Dialog aufegeht, in dem ich nach meiner abgespeicherten Datei suchen kann und schliesslich lade.

Das ganze habe ich mit Delphi 6 erstellt. Ich bin eher ein Anfänger und wollte mal wissen, ob es ohne Riesenaufwand möglich ist.

Benötige ich dazu andere Komponenten? Ich habe leider keine Ahnung wie ich das realisieren soll.

Über einen Link-Tipp, oder direkte Hilfe würde ich mich sehr freuen!

Gruss
Andi

little_budda 5. Jan 2008 11:55

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Hallo Andi44,

du kannst die Felder in eine Ini Speichern.
Dann sparst du dir auch den Weg über den Auswahldialog und du kannst eigene Profilnamen vergeben.


Delphi-Quellcode:

uses ... IniFiles ...

...


procedure SaveEdits;
var resultIniFilePfad : string;
    resultini : tinifile;
    startpfad : string;
begin
  // Vorgabewerte sichern
  getdir(0, startpfad);                           // Eigenen Startpfad einlesen
  if (startpfad[length(startpfad)] <> '\')
    then startpfad := startpfad + '\';            // Pfad ggf. korrigieren
  resultIniFilePfad := frm_main.startpfad + '\base.ini'; // Result Default Values
  if (fileexists(resultIniFilePfad) = True) then        // Wenn das INI File vorhanden ist ...
    begin
      resultini := tinifile.Create(resultIniFilePfad);
        with resultini do
          begin
            writeString('DefaultValues_1', 'Name', ed_0.text);
            writeString('DefaultValues_1', 'drehzahl', ed_1.text);
            writeString('DefaultValues_1', 'untersetzung', ed_2.text);
            writeString('DefaultValues_1', 'steigung', ed_3.text);
          end;
        resultini.free;
    end;

end;

Gruß Holger.
[edit]code[/edit]

Andi44 5. Jan 2008 12:07

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Danke,das geht ja schnell hier! das werde ich einmal versuchen , auszuprobieren, habe ja jetzt viel Lernstoff :)

Wie ist es denn, werden meine Variablen ( drehzahl, untersetzung, etc ) in eine Datei gespeichert?

Wie lade ich sie denn wieder?

Dankeschön!

DeddyH 5. Jan 2008 12:18

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Zitat:

Zitat von Andi44
Wie lade ich sie denn wieder?

Im Prinzip genauso, nur andersherum: IniFile erzeugen und dann so etwas:
Delphi-Quellcode:
ed_0.text := Ini.ReadString('DefaultValues_1','Name','');

little_budda 5. Jan 2008 12:20

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Die Ini Datei aus meinem Beispiel liegt im Pfad deines Programmes.

Die Werte aus deinen Edits liegen in der Datei.

Das Laden ist auch nicht schwer:

Delphi-Quellcode:
procedure ReloadEdits;
var resultIniFilePfad : string;
    resultini : tinifile;
    startpfad : string;
begin
  // Vorgabewerte sichern
  getdir(0, startpfad);                           // Eigenen Startpfad einlesen
  if (startpfad[length(startpfad)] <> '\')
    then startpfad := startpfad + '\';            // Pfad ggf. korrigieren
  resultIniFilePfad := frm_main.startpfad + '\base.ini'; // Result Default Values
  if (fileexists(resultIniFilePfad) = True) then        // Wenn das INI File vorhanden ist ...
    begin
      resultini := tinifile.Create(resultIniFilePfad);
        with resultini do
          begin
           ed_0.text := readString('DefaultValues_1', 'Name', '');
           ed_1.text := readString('DefaultValues_1', 'drehzahl', '');
           ed_2.text := readString('DefaultValues_1', 'untersetzung', '');
           ed_3.text := readString('DefaultValues_1', 'steigung', '');
          end;
        resultini.free;
    end;
end;
Tipp:
Ich würde die Schlüsselnamen separat ablegen, dann kannst du sie über einen Comobox oder List auswählbar machen.
Das ist komfortabeler wenn du mehrere Profile hast, weil sie ja alle in einer Datei liegen.

Gruß Holger.

Twinsetter 5. Jan 2008 12:35

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Er sollte noch ein Editfeld vorsehen wo er die Bezeichnung eingeben kann. Für das von Andi44 gezeigte Beispiel wäre das DefaultValues_1.

Der Code würde dann auszugsweise wie folgt aussehen:

Delphi-Quellcode:
begin
  writeString(ed_4.text, 'Name', ed_0.text);
  writeString(ed_4.text, 'drehzahl', ed_1.text);
  writeString(ed_4.text, 'untersetzung', ed_2.text);
  writeString(ed_4.text, 'steigung', ed_3.text);
end;
ed_4.text ist der Bezeichner für das neue Editfeld.

Nicht so gut an dieser Methode ist, daß bei Vergabe eines gleichen Abschnitsbezeichners vorhandene Daten überschrieben werden.

little_budda 5. Jan 2008 12:39

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Aber er kann doch vor dem schreiben prüfen ob der Schlüssel schon existiert ...

grenzgaenger 5. Jan 2008 12:54

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
ist dafür nicht seit TP6 das konzept der streams mit der serializierung implementiert worden? Ich erinnere mich dunkel... hatte das bislang noch nie gebraucht. aber das wäre 'n klassischer fall. sollte mit 'n paar tastendrücken erledigt sein...

vielleicht weiss jemand wie das geht und kennt 'n tutorial... :-)

Andi44 5. Jan 2008 13:03

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
ich weiss nicht, ob ich das richtig verstehe, aber ich wollte für meine Dateien immer verschiedene Dateinamen haben.

Also zum Beispiel so:

untersetzung 2
drehzahl 5500
steigung 20

das ganze speichere ich unter z.B. Andis_Boot.xyz

wenn die EditFelder nun die daten eines anderen Bootes enthalten

utersetzung: 1.75
drehzahl 6000
steigung 24

dann wieder in eine Datei speichern z.B. Werners_Boot.xyz

so dass ich eben mehrere Dateien habe , die ich wieder einlesen kann wenn ich möchte.

einen Öffnen bzw. speichern dialog habe ich mit der vorgenannten methode wohl nicht, oder?
Das wäre für die Bediener schon recht sinnvoll, da viele Benutzer mit verschiedenen Boot/Motor Kombinationen herumtesten um die zu erwartende geschwindigkeit zu haben :)
So werden schon ein paar Dateien entstehen, denke ich.

gruss
Andi

DeddyH 5. Jan 2008 13:05

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Da wären vielleicht typisierte Dateien oder besser eine kleine Datenbank eine Überlegung wert.

sirius 5. Jan 2008 13:08

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Die Idee mit EINEM Ini-File finde ich sehr schön. Ich würde allerdings nicht ein Edit4-Feld nehmen, sondern beim Klicken auf den Speichern- bzw. Laden button einen InputDialog bzw. eine Combobox anzeigen. So ist der Ablauf für den User besser nachvollziehbar. Ausserdem wäre es zu überlegen, die Ini nicht ins Programmverzeichns zu legen.


Ungeachtet dessen, dass ich (soweit ich das Projekt überblicke) wahrscheinlich auch die Ini-Lösung vorziehen würde, möchte ich noch kurz die programmtechnische Umsetzung von Andis eigener Idee zeigen Ich nehme für die Dateiarbeit ein TFilestream. Wenn man die Datei auch händig bearbeiten soll, wäre ein Textfile besser. Aber in dem Fall ist die Ini-Lösung gleich noch 10mal besser.

Delphi-Quellcode:
uses Dialogs;

procedure TForm1.SpeichernButtonClick(Sender: TObject);
var SaveDialog:TSaveDialog;
    Datei:TFileStream;
    i:integer;
    stext:string;
    textlength:integer;
begin
  SaveDialog:=TSavedialog.Create(nil);
  try
    SaveDialog.Filter:='Motoren (*.mot)|*.mot';
    savedialog.DefaultExt:='mot';
    if SaveDialog.Execute then
    begin
      Datei:=TfileStream.Create(SaveDialog.FileName,fmCreate);
      try
        for i:=1 to 3 do
        begin
          stext:=TEdit(findcomponent('Edit'+inttostr(i))).Text;
          textlength:=length(stext);
          Datei.Write(textlength,sizeof(textlength));
          Datei.Write(stext[1],textlength);
        end;
      finally
        Datei.free;
      end;
    end;
  finally
    SaveDialog.Free;
  end;
end;

procedure TForm1.LadenButtonClick(Sender: TObject);
var OpenDialog:TOpenDialog;
    Datei:TFileStream;
    i:integer;
    stext:string;
    textlength:integer;
begin
  OpenDialog:=TOpendialog.Create(nil);
  try
    OpenDialog.Filter:='Motoren (*.mot)|*.mot|Alle Dateien|*.*';
    if OpenDialog.Execute then
    begin
      Datei:=TfileStream.Create(OpenDialog.FileName,fmOpenRead);
      try
        for i:=1 to 3 do
        begin
          Datei.Read(textlength,sizeof(textlength));
          setlength(stext,textlength);
          Datei.Read(stext[1],textlength);
          TEdit(findcomponent('Edit'+inttostr(i))).Text:=stext;
        end;
      finally
        Datei.free;
      end;
    end;
  finally
    OpenDialog.Free;
  end;
end;

Andi44 5. Jan 2008 13:13

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Das ist eine menge "input"

ich habe zwischenzeitlich google versucht zu befragen, da kam dann so etwas heraus:

Zitat:

procedure TForm1.Button1Click(Sender: TObject);
const Anzahl : integer = 20;
var sl: TStringlist;
i : integer;
begin
if SaveDialog1.Execute then
begin
sl:= TStringlist.Create;
for i:=1 to Anzahl do
begin
sl.Add(TEdit(FindComponent('Edit'+IntToStr(i))).Te xt);
end;
sl.SaveToFile(SaveDialog1.Filename);
sl.free;
end;
end;
Da scheint auch der dialog an sich vorhanden zu sein.

sirius 5. Jan 2008 13:15

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Jep, den Dialog findest du irgendwo in deiner Palette und kannst auf das Form ziehen.
Die Stringlist ist (sofern du immer Text hast) ein bisschen schöner.

grenzgaenger 5. Jan 2008 13:40

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
hier 'n serializierungsbeispiel

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    bClear: TButton;
    bSave: TButton;
    bLoad: TButton;
    procedure bClearClick(Sender: TObject);
    procedure bSaveClick(Sender: TObject);
    procedure bLoadClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.bClearClick(Sender: TObject);
begin
 Edit1.Text := '';
 Edit2.Text := '';
 edit3.text := '';
end;

procedure TForm1.bLoadClick(Sender: TObject);
var
 fs: tFileStream;
begin
  fs := tFileStream.Create(paramstr(0)+'.save', fmOpenReadWrite);
  fs.ReadComponent(edit1);
  fs.ReadComponent(edit2);
  fs.ReadComponent(edit3);
  fs.free;
end;

procedure TForm1.bSaveClick(Sender: TObject);
var
 fs: tFileStream;
begin
 fs := tFileStream.Create(paramstr(0)+'.save', fmCreate or fmOpenReadWrite);
 fs.WriteComponent(edit1);
 fs.WriteComponent(edit2);
 fs.WriteComponent(edit3);
 fs.free;
end;

end.

Twinsetter 5. Jan 2008 18:38

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
@ grenzgaenger
Deine Lösung ist quelltextmäßig sehr kurz und auch elegant, bei der Angabe des Dateinamens ist DIr aber ein Fehler unterlaufen. Bei Deinem Code würde zum ersten jedesmal die Datendatei überschrieben, da Du den Dateinamen nicht änderst. Du verwendest mit Paramstr(0) den Namen Deines Programmes dem Du einfach nur die Extention .save dranhängst. Der Filename würde dann beispielsweise MeinProgramm.exe.save lauten.

Zum andern speicherst Du mit dieser Methode die kompletten TEdit-Objekte mit allen Properties ab. Abgesehen davon das dies unnötig Speicherplatz kostet - was heutzutage siche keine Rolle spielt - dürfte es aber auch Probleme beim Einlesen geben wenn später einmal das GUI geändert wird und alte gespeicherte Daten wieder eingelesen werden.

Für dieses Problem gibt es eigentlich nur zwei vernünftige Lösungen
1. mit Inidatei - man kann sie ja jedesmal mit einem andern Namen abspeichern
2. die klassische Methode mit einem Record und einen File vom Typ Recocord

Ich persönlich würde hier aber die Inimethode vorziehen.
Ach so - es auch gibt noch eine dritte Variante, die ich persönlich ganz gut finde - indizierte Stringliste.
z.B:
Delphi-Quellcode:
procedure SaveToFile(Datei:string)
var
  Liste : TStringlist
begin
  Liste:=TStringList.Create;
  Liste.Add('Name='+ed_0.text);
  Liste.Add('drehzahl='+ed_1.text);
  Liste.Add('untersetzung='+ed_2.text);
  Liste.Add('steigung='+ed_3.text);
  Liste.SaveToFile(Datei);
  Liste.Free;
end;


procedure LoadFromFile(Datei:string)
var
  Liste : TStringlist
begin
  Liste:=TStringList.Create;
  Liste.LoadFromFile(Datei)
  ed_0.text:=Liste.IndexOf('Name');
  ed_1.text:=Liste.IndexOf('drehzahl');
  ed_2.text:=Liste.IndexOf('untersetzung');
  ed_3.text:=Liste.IndexOf('steigung');
  Liste.Free;
end;
Diesen Proceduren wird beim Aufruf nur ein Dateiname übergeben der zum Beispiel über einen Speichern- bzw. Öffnendialog erzeugt wird. Dateiname und Extention sind vollig frei wählbar. Vorteil dieser Sache ist, daß die Dateien reine Textdateien sind und somit mit jedem Editor gelesen werden können wenn das Programm mal nicht verfügbar ist. Auch Einlesen mit Excel wäre möglich und sogar gut lesbar.

Andi44 6. Jan 2008 23:04

Re: EDIT Inhalte in Datei abspeichern und wieder laden
 
Hallo!

Ich habe es nun mit der Methode von Sirius gelöst.

Zitat:

uses Dialogs;

procedure TForm1.SpeichernButtonClick(Sender: TObject);
var SaveDialog:TSaveDialog;
Datei:TFileStream;
i:integer;
stext:string;
textlength:integer;
begin
SaveDialog:=TSavedialog.Create(nil);
try
SaveDialog.Filter:='Motoren (*.mot)|*.mot';
savedialog.DefaultExt:='mot';
if SaveDialog.Execute then
begin
Datei:=TfileStream.Create(SaveDialog.FileName,fmCr eate);
try
for i:=1 to 3 do
begin
stext:=TEdit(findcomponent('Edit'+inttostr(i))).Te xt;
textlength:=length(stext);
Datei.Write(textlength,sizeof(textlength));
Datei.Write(stext[1],textlength);
end;
finally
Datei.free;
end;
end;
finally
SaveDialog.Free;
end;
end;

procedure TForm1.LadenButtonClick(Sender: TObject);
var OpenDialog:TOpenDialog;
Datei:TFileStream;
i:integer;
stext:string;
textlength:integer;
begin
OpenDialog:=TOpendialog.Create(nil);
try
OpenDialog.Filter:='Motoren (*.mot)|*.mot|Alle Dateien|*.*';
if OpenDialog.Execute then
begin
Datei:=TfileStream.Create(OpenDialog.FileName,fmOp enRead);
try
for i:=1 to 3 do
begin
Datei.Read(textlength,sizeof(textlength));
setlength(stext,textlength);
Datei.Read(stext[1],textlength);
TEdit(findcomponent('Edit'+inttostr(i))).Text:=ste xt;
end;
finally
Datei.free;
end;
end;
finally
OpenDialog.Free;
end;
end;
Was soll ich sagen?

Es ist exakt so, wie ich mir das vorgestellt hatte - Allerbesten Dank dafür!!!!!

Klasse, dass einem so schnell hier geholfen wird! :)


gruss
Andi


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:04 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