Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   ListView und Textdatei (https://www.delphipraxis.net/52889-listview-und-textdatei.html)

MaM 6. Sep 2005 10:04


ListView und Textdatei
 
Hallo,

nachdem ich das Forum durchsucht hatte und Beiträge fand, bei denen auf andere Treads verweist wurde und ich die Lösung für mein Problem nicht rausfiltern konnte frage ich einfach mal.

Ich habe eine Form bei Editfeldern und Memos. Die eingetragenen Werte sollen in eine Textdatei geschrieben werden. Die einzelnen Einträge sind durch Simikolons getrennt.

Delphi-Quellcode:
procedure TForm_Kundenhinzufuegen.Button1Click(Sender: TObject);
var sl: TStringList;
begin
  sl:=TStringList.Create; //Objekt erzeugen
  // Objekt wird freigegeben falls Fehler auftreten
  try
    // Einträge der Textdatei hinzufügen
    sl.Add(E_Firma.Text + ';' +  E_Nachname.Text + ';' +  E_Vorname.Text + ';' +  E_Strasse.Text + ';' +  E_Plz.Text + ';' +  E_Ort.Text + ';' +  CB_Land.Text + ';' +  E_Telefon.Text + ';' +  E_Fax.Text + ';' +  E_Mobiltelefon.Text + ';' +  E_eMail.Text + ';' +  E_Zustaendigkeit.Text + ';' +  E_Auslieferungsdatum.Text + ';' +  E_Planungsende.Text + ';' +  M_Ansprechpartner.Text); //Text hinzufügen
    sl.SaveToFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt'); //Datei speichern
  finally
    sl.free; //Objekt wieder freigeben
  end;
end;
Das klappt soweit ganz gut. Nur was muss ich einfügen, damit bei neuen Einträgen der alte Datensatz nicht überschrieben wird?


Das 2. Problem ist das Auslesen der Daten im ListView. Das bekomme ich garnicht hin.




MaM

marabu 6. Sep 2005 11:51

Re: ListView und Textdatei
 
Hallo MaM,

Zitat:

Zitat von MaM
Die eingetragenen Werte sollen in eine Textdatei geschrieben werden. Die einzelnen Einträge sind durch Simikolons getrennt.

Einfaches Trennen durch Semikolon führt zu Problemen, sobald in einem Feld das Trennzeichen selbst im Inhalt vorkommt. Das Problem kannst du so lösen:

Delphi-Quellcode:
function TForm_Kundenhinzufuegen.NeueZeile: string;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Delimiter := ';';
  sl.Add(E_Firma.Text);
  ...
  Result := sl.DelimitedText;
  sl.Free;
end;
Damit deine gerade erzeugte Datenzeile nicht die zuvor gespeicherte überschreibt, musst du alle Daten im Hauptspeicher halten:

Delphi-Quellcode:
// Im Hauptspeicher halten
procedure TForm_Kundenhinzufuegen.FormCreate(...);
begin
  slDaten := TStringList.Create;
  slDaten.LoadFromFile(KundenFileName);
end;

procedure TForm_Kundenhinzufuegen.FormDestroy(...);
begin
  slDaten.SaveToFile(KundenFileName);
  slDaten.Free;
end;

procedure TForm_Kundenhinzufuegen.AppendButtonClick(Sender: TObject);
begin
  slDaten.Add(NeueZeile);
end;
Alternativ kannst du die Textdatei einfach fortschreiben:

Delphi-Quellcode:
procedure TForm_Kundenhinzufuegen.AppendButtonClick(Sender: TObject);
begin
  AssignFile(f, KundenFileName);
  Append(f)
  WriteLn(f, NeueZeile);
  CloseFile(f);
end;
Für die Übernahme der Daten in eine ListView stehen dir zwei Techniken zur Verfügung - ich lege dir die virtuelle ListView nahe. Schau mal in der Online-Hilfe unter TListView.OwnerData nach. Wenn du dann noch Fragen hast, hilft dir hier bestimmt jemand.

Grüße vom marabu

MaM 6. Sep 2005 13:07

Re: ListView und Textdatei
 
Ich bekomme als Fehlermeldung: Undefinierter Bezeichner: Delimiter.

Liegt das an der Sofware-Version?




MaM

marabu 6. Sep 2005 13:48

Re: ListView und Textdatei
 
Allerdings - tut mir leid.

Musst du denn das Semikolon verwenden? Wenn du auf Komma umsteigst, dann kannst du so arbeiten:

Delphi-Quellcode:
function TForm_Kundenhinzufuegen.NeueZeile: string;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add(E_Firma.Text);
  ...
  Result := sl.CommaText;
  sl.Free;
end;
Ich würde dir das empfehlen, da es eigentlich ein Standard ist, den auch andere Programme sehr gut verarbeiten können.

Andernfalls kannst du dir vielleicht erstmal so helfen:

Delphi-Quellcode:
function TForm_Kundenhinzufuegen.NeueZeile: string;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add(E_Firma.Text);
  ...
  Result := StringReplace(sl.CommaText, ',', ';', [rfReplaceAll]);
  sl.Free;
end;
Grüße vom marabu

MaM 6. Sep 2005 14:39

Re: ListView und Textdatei
 
Als undefinierter Bezeichner wird ebenfalls "NeueZeile" definiert.



MaM

Sharky 6. Sep 2005 15:00

Re: ListView und Textdatei
 
Zitat:

Zitat von MaM
Als undefinierter Bezeichner wird ebenfalls "NeueZeile" definiert.

Hai MaM,

Du must die Funktion NeueZeile natürlich als Methode deiner TForm_Kundenhinzufuegen deklarieren.

MaM 6. Sep 2005 16:25

Re: ListView und Textdatei
 
Dann kommt die Meldung, Funktion benötigt Ergebnistyp.




MaM

marabu 6. Sep 2005 16:30

Re: ListView und Textdatei
 
Hast du denn die Funktion im private Abschnitt deiner Form richtig eingetragen?

Delphi-Quellcode:
interface

type
  TForm_Kundenhinzufuegen = class(TForm)
  ...
  private
    function NeueZeile: string;
  ...
  end;
marabu

MaM 7. Sep 2005 10:18

Re: ListView und Textdatei
 
Bei der Hinzufügenprozedur mit Button, kommt die Fehlermeldung, dass die Variable slDaten wahrscheinlich nicht initialisiert wurde. Das ist ebenfalls bei der FormDestoy-Prozedur so.
slDaten ist als variable definiert (var slDaten: TStringList;).



MaM

marabu 7. Sep 2005 11:12

Re: ListView und Textdatei
 
Na, das ist doch mal eine aussagekräftige Fehlermeldung. Was sagt denn der Compiler zu der Zeile in FormCreate(), in der du die Objekt-Variable slDaten initialisierst? (siehe mein erstes posting)

Grüße vom marabu

MaM 7. Sep 2005 12:33

Re: ListView und Textdatei
 
So, die Fehlermeldung konnte ich abschalten. Nur habe ich jetzt das Problem, dass die Werte nicht mehr in die Textdatei geschrieben werden.

Code:
Delphi-Quellcode:
unit Kundenhinzufuegen;

interface

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

type
  TForm_Kundenhinzufuegen = class(TForm)
    L_KdNr: TLabel;
    GB_Kundendaten: TGroupBox;
    E_Firma: TEdit;
    E_Nachname: TEdit;
    L_Firma: TLabel;
    L_Nachname: TLabel;
    L_Vorname: TLabel;
    GB_Anschrift: TGroupBox;
    L_Strasse: TLabel;
    L_Plz: TLabel;
    L_Ort: TLabel;
    E_Strasse: TEdit;
    E_Plz: TEdit;
    E_Vorname: TEdit;
    E_Ort: TEdit;
    L_Land: TLabel;
    GB_Kontakt: TGroupBox;
    L_Telefon: TLabel;
    L_Fax: TLabel;
    L_Mobiltelefon: TLabel;
    L_eMail: TLabel;
    E_Telefon: TEdit;
    E_Fax: TEdit;
    E_Mobiltelefon: TEdit;
    E_eMail: TEdit;
    GroupBox1: TGroupBox;
    M_Ansprechpartner: TMemo;
    CB_Land: TComboBox;
    E_KdNr: TEdit;
    GroupBox2: TGroupBox;
    L_Zustaendigkeit: TLabel;
    L_Auslieferungsdatum: TLabel;
    E_Zustaendigkeit: TEdit;
    E_Auslieferungsdatum: TEdit;
    B_Hinzufuegen: TButton;
    B_Abbrechen: TButton;
    Label1: TLabel;
    E_Planungsende: TEdit;
    procedure B_HinzufuegenClick(slDaten: TStringList);
    procedure FormCreate(slDaten: TStringList);
    procedure B_AbbrechenClick(Sender: TObject);
    procedure FormDestroy(slDaten: TStringList);
  private
    function NeueZeile: string;
.
.
.

function TForm_Kundenhinzufuegen.NeueZeile: string;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add(E_Firma.Text);
  sl.Add(E_Nachname.Text);
  sl.Add(E_Vorname.Text);
  sl.Add(E_Strasse.Text);
  sl.Add(E_Plz.Text);
  sl.Add(E_Ort.Text);
  sl.Add(CB_Land.Text);
  sl.Add(E_Telefon.Text);
  sl.Add(E_Fax.Text);
  sl.Add(E_Mobiltelefon.Text);
  sl.Add(E_eMail.Text);
  sl.Add(E_Zustaendigkeit.Text);
  sl.Add(E_Auslieferungsdatum.Text);
  sl.Add(E_Planungsende.Text);
  sl.Add(M_Ansprechpartner.Text);
  sl.Add(E_Firma.Text);
  Result := sl.CommaText;
  sl.Free;
end;


procedure TForm_Kundenhinzufuegen.B_HinzufuegenClick(slDaten: TStringList);
begin
  slDaten.Add(NeueZeile);
end;

procedure TForm_Kundenhinzufuegen.FormCreate(slDaten: TStringList);
begin
  slDaten := TStringList.Create;
  slDaten.LoadFromFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt');
end;

procedure TForm_Kundenhinzufuegen.B_AbbrechenClick(Sender: TObject);
begin
  Close;
end;

procedure TForm_Kundenhinzufuegen.FormDestroy(slDaten: TStringList);
begin
  slDaten.SaveToFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt');
  slDaten.Free;
end;
Gibt es ggf. noch Verbesserungsvorschläge zu dem Code?



MaM

Sharky 7. Sep 2005 12:53

Re: ListView und Textdatei
 
Hai MaM,

ich glaube Du hast da ein Verständniss problem ;-)
Du erzeugst für jede deiner Methoden eine lokale Version slData deiner TStringList.
Damit ist diese natürlich lehr wenn Du sie im OnDestroy speicherst. Du brauchst also eine Instanz von TStringList welche zur gesamten Laufzeit des Programmes vorhanden ist.

hier einmal ein Beispiel:
Delphi-Quellcode:
type
  TForm_Kundenhinzufuegen = class(TForm)
    B_Hinzufuegen: TButton;
    procedure B_HinzufuegenClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    slDaten : TStringList; // Die "globale" Instanz
    function NeueZeile : string;
  public
    { Public-Deklarationen }

  end;

implementation

{$R *.dfm}

function TForm_Kundenhinzufuegen.NeueZeile: string;
var
  sl: TStringList;
begin
// .
// So wie Du sie hast.
// .
end;

procedure TForm_Kundenhinzufuegen.FormCreate(Sender: TObject);
begin
  slDaten := TStringList.Create;
  slDaten.LoadFromFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt');
end;

procedure TForm_Kundenhinzufuegen.FormDestroy(Sender: TObject);
begin
  slDaten.SaveToFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt');
  slDaten.Free;
end;

procedure TForm_Kundenhinzufuegen.B_HinzufuegenClick(Sender: TObject);
begin
  slDaten.Add(NeueZeile);
end;

MaM 7. Sep 2005 13:21

Re: ListView und Textdatei
 
Leider schreibt er dennoch nichts in die Datei.


Delphi-Quellcode:
type
  TForm_Kundenhinzufuegen = class(TForm)
.
.
.

  private
    { Private-Deklarationen }
    slDaten : TStringList; // Die "globale" Instanz
    function NeueZeile: string;

.
.
.

function TForm_Kundenhinzufuegen.NeueZeile: string;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add(E_Firma.Text);
  sl.Add(E_Nachname.Text);
  sl.Add(E_Vorname.Text);
  sl.Add(E_Strasse.Text);
  sl.Add(E_Plz.Text);
  sl.Add(E_Ort.Text);
  sl.Add(CB_Land.Text);
  sl.Add(E_Telefon.Text);
  sl.Add(E_Fax.Text);
  sl.Add(E_Mobiltelefon.Text);
  sl.Add(E_eMail.Text);
  sl.Add(E_Zustaendigkeit.Text);
  sl.Add(E_Auslieferungsdatum.Text);
  sl.Add(E_Planungsende.Text);
  sl.Add(M_Ansprechpartner.Text);
  sl.Add(E_Firma.Text);
  Result := sl.CommaText;
  sl.Free;
end;


procedure TForm_Kundenhinzufuegen.FormCreate(Sender: TObject);
begin
  slDaten := TStringList.Create;
  slDaten.LoadFromFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt');
end;

procedure TForm_Kundenhinzufuegen.FormDestroy(Sender: TObject);
begin
  slDaten.SaveToFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt');
  slDaten.Free;
end;

procedure TForm_Kundenhinzufuegen.B_HinzufuegenClick(Sender: TObject);
begin
  slDaten.Add(NeueZeile);
end;

procedure TForm_Kundenhinzufuegen.B_AbbrechenClick(Sender: TObject);
begin
  Close;
end;

MaM

Sharky 7. Sep 2005 14:01

Re: ListView und Textdatei
 
Zitat:

Zitat von MaM
Leider schreibt er dennoch nichts in die Datei.

Ich habe es nicht getestet. Aber setze das slDaten.SaveToFile(ExtractFilePath(Application.Exe Name)+'data\kunden.txt'); einmal in das OnClose der Form und nicht in das OnDestroy.

MaM 7. Sep 2005 14:50

Re: ListView und Textdatei
 
Nein, auch das hat nicht funktioniert.

Habe das ganze jetzt erstmal so umgebaut. Da ich Zugriffsfehlermeldungen bekommen hatte. Nachdem ich die Form geschlossen habe.

Delphi-Quellcode:
procedure TForm_Kundenhinzufuegen.B_HinzufuegenClick(Sender: TObject);
begin
  slDaten := TStringList.Create;
  slDaten.LoadFromFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt');
  try
  slDaten.Add(NeueZeile);
  slDaten.SaveToFile(ExtractFilePath(Application.ExeName)+'data\kunden.txt');
  finally
  slDaten.Free;
end;
end;


MaM

MaM 12. Sep 2005 14:50

Re: ListView und Textdatei
 
*schieb*



MaM

marabu 12. Sep 2005 20:11

Re: ListView und Textdatei
 
Hi MaM,

überlege doch mal mit: Für die Pflege eines Kundenstammes hast du normalerweise eine MainForm, auf der alle Kunden visualisiert werden (ListView?) und einen KundenDialog, auf dem die Detailinformationen zu einem Kunden erfasst oder bearbeitet werden können. Außerdem brauchst du so etwas wie ein Datenmodul - eine normale Unit ist OK, solange du mit der Speicherung deiner Kundendaten in einer Textdatei experimentierst.

Die StringList, mit der du die Kundendaten im Hauptspeicher verwaltest, gehört dann in dieses Datenmodul, damit von der MainForm und vom KundenDialog darauf zugegriffen werden kann. Kriegst du das hin?

Grüße vom marabu


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