Delphi-PRAXiS
Seite 1 von 3  1 23   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TStringlist wieder mit Trennzeichen speichern (https://www.delphipraxis.net/203164-tstringlist-wieder-mit-trennzeichen-speichern.html)

zaphood 19. Jan 2020 21:52

TStringlist wieder mit Trennzeichen speichern
 
Hallo Forum Gemeinde,
ich habe folgendes Problem das ich eine txt Datei mit Daten einlesen und verändern möchte. Die Datei ist mit Trennzeichen aufgebaut und muss auch wieder so gespeichert werden.
Momentan stehe ich auf dem Schlauch und glaube das TStringlist nicht dafür geeignet ist.

Gewünschtes Ziel ist:
String Eingang = 0193433020;2301000953;CNC-DB;3302060000;drehen01;300;;;;
String Ausgang = 2301000953;10;3302060000;1;1;;193433020;

Aufbau der Ausgabe was ich bisher geschafft habe:
2301000953 CR/LF
10 CR/LF
3302060000 CR/LF
1 CR/LF
1 CR/LF
; CR/LF
0193433020 CR/LF
;CR/LF
CR/LF
CR/LF
CR/LF
CR/LF

Das Umsortieren der Reihenfolge und hinzufügen von weiteren Daten hat geklappt aber leider mit Steuerzeichen und nicht wie gewünscht in einer Zeile.

Bitte um Tips ob ich mit TStringList das erreichen kann oder total falsch liege.
Danke und Gruß

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  sl : tstringlist;           //
begin
  sl := TStringList.Create;
  sl.Delimiter := ';';       //
  sl.DelimitedText := '0193433020;2301000953;CNC-DB;3302060000;drehen01;300;;;;';
  sl.delete(2);
  sl.delete(3);
  sl.Move(1,0);
  sl.insert(1,'10');
  sl.Move(3,2);
  sl.insert(3,'1');
  sl.insert(4,'1');
  sl.insert(5,' ');
  sl.SaveToFile('d:\SPC.dat');
  sl.Free;
end;

zaphood 21. Jan 2020 07:27

AW: TStringlist wieder mit Trennzeichen speichern
 
Das Problem ist gelöst, es wird alles in einer Zeile geschrieben und ohne Steuerzeichen.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

var
  sl : tstringlist;
  s0, s1, s2, s3, s4, s5 : String;
  Datei   : TextFile;
  Filename : String;
  Datum   : String;

begin
  sl := TStringList.Create;
  sl.Delimiter := ';';       //
  sl.DelimitedText := '0193433020;2301000953;CNC-DB;3302060000;drehen01;300;';
  s0 := sl.Strings[0]; //1. Autragsnummer
  s1 := sl.Strings[1]; //2. Artikelnummer
  s2 := sl.Strings[2]; //3. Messtation
  s3 := sl.Strings[3]; //4. Kapazität
  s4 := sl.Strings[4]; //5. Prüfablauf
  s5 := sl.Strings[5]; //6. Anzahl Teile
  Datum   := FormatDateTime('yyyy_mm_dd__hh_mm_ss', Now);
  Filename := 'BDECN ' + Datum + '.dat';
  AssignFile(Datei, Filename);
  Rewrite(Datei);
  write(Datei, s1);
  write(Datei, ';');
  write(Datei, '10');
  write(Datei, ';');
  write(Datei, s3);
  write(Datei, ';');
  write(Datei, '1');
  write(Datei, ';');
  write(Datei, '1');
  write(Datei, ';');
  write(Datei, ';');
  write(Datei, s0);
  write(Datei, ';');
  CloseFile(Datei);
  sl.Free;
end;

mkinzler 21. Jan 2020 08:08

AW: TStringlist wieder mit Trennzeichen speichern
 
Da würde dann aber ein
Delphi-Quellcode:
WriteLn( sl.DelimitedText);
reichen

himitsu 21. Jan 2020 08:34

AW: TStringlist wieder mit Trennzeichen speichern
 
Und ein Ressourcenschutzblock, falls es beim Rewrite knallt, weil die Datei nicht geschrieben werden kann, und dann ein Speicherleck entsteht.

Ich weiß nicht ob es im FPC sowas gibt, aber warum sollte es sowas nicht geben.

In Delphi gibt es die IOUtils:
Delphi-Quellcode:
TFile.WriteAllText(Filename, SL.DelimitedText);

Und dann gibt es natürlich auch noch den TFileStream, welchen man ebenfalls gern benutzen darf.

zaphood 22. Jan 2020 07:37

AW: TStringlist wieder mit Trennzeichen speichern
 
Danke das jemand draufgeschaut hat und für die Tipps mit dem Ressourcenschutzblock usw. :) Das versuche ich noch einzubauen.
Jetzt knallt es tatsächlich und ich verstehe nicht warum.

Die Zeichenkette hatte ich für die ersten Testzwecke im Programm eingebaut
Delphi-Quellcode:
sl.DelimitedText := '0193433020;2301000953;CNC-DB;3302060000;drehen01;300;';


Nun möchte ich die Textdatei laden, welche exakt genauso aussieht und es kommt zu einem EStringListError - list index(1) out of bounds
Delphi-Quellcode:
sl.LoadFromFile('SPC.txt'); //Datei in Stringliste laden


Im Einzelschritt passiert es bei folgender Zeile.
Delphi-Quellcode:
Auftragsnummer := sl.Strings[0];


Mit ShowMessage(sl.DelimitedText) habe ich mir die Zeichenkette angesehen und mir ist aufgefallen, dass sie unterschiedlich aussieht.
0193433020;2301000953;CNC-DB;3302060000;drehen01;300; -> alles ok Zeichenkette im Programm
"0193433020;2301000953;CNC-DB;3302060000;drehen01;300;" -> mit LoadFromFile steht die Kette auf einmal in "...."


Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  sl : tstringlist;
  Auftragsnummer, Artikelnummer, Messstation, Kapazitaet : String;
  Datei   : TextFile;
  Filename : String;
  Datum   : String;
  log     : String;

begin
  sl := TStringList.Create;
  sl.Delimiter := ';';
  sl.LoadFromFile('SPC.txt'); //Datei in Stringliste laden
  //sl.DelimitedText := '0193433020;2301000953;CNC-DB;3302060000;drehen01;300;';
  ShowMessage(sl.DelimitedText);
  Auftragsnummer := sl.Strings[0];
  Artikelnummer := sl.Strings[1];
  Messstation   := sl.Strings[2];
  Kapazitaet    := sl.Strings[3];
  ShowMessage(sl.DelimitedText);
  Datum   := FormatDateTime('yyyy_mm_dd__hh_mm_ss', Now);
  Filename := 'BDECN ' + Datum + '.dat';
  log := Datum+' '+sl.DelimitedText;
  if Messstation = 'RB' then
    begin
     Meldung.Caption := 'skip RB';
     logdatei(log);
    end
  else
    if Messstation = 'CNC-FB' then
    begin
     Meldung.Caption := 'skip CNC-FB';
     logdatei(log);
    end
  else
  begin
   Meldung.Caption := 'Datei ok';
   logdatei(log);
   AssignFile(Datei, Filename);
   Rewrite(Datei);
   write(Datei, Artikelnummer);
   write(Datei, ';');
   write(Datei, '10');
   write(Datei, ';');
   write(Datei, Kapazitaet);
   write(Datei, ';');
   write(Datei, '1');
   write(Datei, ';');
   write(Datei, '1');
   write(Datei, ';');
   write(Datei, ';');
   write(Datei, Auftragsnummer);
   write(Datei, ';');
   CloseFile(Datei);
   sl.Free;
  end;
end;
end.

Klaus01 22. Jan 2020 08:04

AW: TStringlist wieder mit Trennzeichen speichern
 
.. wenn Du die Datei mit loadFromFile in die StringList lädst
und Du anschliessend sl.delimitedText hast Du die ganze Datei dadrin ... ist dann der ganze Rest.

Was Du vielleicht möchtest ist die pro Zeile den delimited Text anschauen/bearbeite.
Dan musst Du pro TextZeile den Inhalt in eine andere StringList übergeben und diese dann verarbeiten.

Im Prinzip so:
Delphi-Quellcode:
for i:= 0 to sl.count -1 do
  begin
    slZeile := sl.create;
    try
      slZeile.delimitedText := sl[i];
      slZeile[0]...
      slZeile[1] ..
    finally
      slZeile.free;
    end;
  end;
Grüße
Klaus

Luckie 22. Jan 2020 09:01

AW: TStringlist wieder mit Trennzeichen speichern
 
Der Ressourcenschutzblock (try-finaly) fehlt aber immer noch.

Blup 22. Jan 2020 10:13

AW: TStringlist wieder mit Trennzeichen speichern
 
nicht getestet:
Delphi-Quellcode:
unit CSVHelper;

interface

uses
  Classes, SysUtils;

type
  TStringListCSVHelper = class helper for TStringList
  public
    procedure LoadFromCSVStream(Stream: TStream); overload; virtual;
    procedure LoadFromCSVStream(Stream: TStream; Encoding: TEncoding); overload; virtual;
    procedure LoadFromCSVFile(const FileName: string); overload; virtual;
    procedure LoadFromCSVFile(const FileName: string; Encoding: TEncoding); overload; virtual;
    procedure SaveToCSVStream(Stream: TStream); overload; virtual;
    procedure SaveToCSVStream(Stream: TStream; Encoding: TEncoding); overload; virtual;
    procedure SaveToCSVFile(const FileName: string); overload; virtual;
    procedure SaveToCSVFile(const FileName: string; Encoding: TEncoding); overload; virtual;
  end;

implementation

{TStringListCSVHelper]}

procedure TStringListCSVHelper.LoadFromCSVStream(Stream: TStream);
var
  Buffer: TBytes;
  Encoding: TEncoding;
begin
  Stream.ReadData(Buffer);
  TEncoding.GetBufferEncoding(Buffer, Encoding);
  DelimitedText := Encoding.GetString(Buffer);
end;

procedure TStringListCSVHelper.LoadFromCSVStream(Stream: TStream; Encoding: TEncoding);
var
  Buffer: TBytes;
begin
  Stream.ReadData(Buffer);
  DelimitedText := Encoding.GetString(Buffer);
end;

procedure TStringListCSVHelper.LoadFromCSVFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName);
  try
    LoadFromCSVStream(Stream);
  finally
    Stream.Free;
  end;
end;

procedure TStringListCSVHelper.LoadFromCSVFile(const FileName: string; Encoding: TEncoding);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  try
    LoadFromCSVStream(Stream, Encoding);
  finally
    Stream.Free;
  end;
end;

procedure TStringListCSVHelper.SaveToCSVStream(Stream: TStream);
begin
  SaveToCSVStream(Stream, Encoding);
end;

procedure TStringListCSVHelper.SaveToCSVStream(Stream: TStream; Encoding: TEncoding);
var
  Buffer: TBytes;
begin
  Buffer := Encoding.GetBytes(DelimitedText);
  Stream.WriteData(Buffer);
end;

procedure TStringListCSVHelper.SaveToCSVFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenWrite);
  try
    SaveToCSVStream(Stream);
  finally
    Stream.Free;
  end;
end;

procedure TStringListCSVHelper.SaveToCSVFile(const FileName: string; Encoding: TEncoding);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenWrite);
  try
    SaveToCSVStream(Stream, Encoding);
  finally
    Stream.Free;
  end;
end;

end.
Delphi-Quellcode:
uses
  CSVHelper;
 
function BuildFilename(DateTime: TDateTime): string;
begin
  Result := 'BDECN ' + FormatDateTime('yyyy_mm_dd__hh_mm_ss', DateTime) + '.dat';
end;

procedure SaveData(MyCSV: TStringList);
begin
  MyCSV.Delimiter := ';';
  MyCSV.StrictDelimiter := True;
  MyCSV.SaveToCSVFile(BuildFilename(Now));
end;

procedure LoadData(MyCSV: TStringList);
begin
  MyCSV.Delimiter := ';';
  MyCSV.StrictDelimiter := True;
  MyCSV.LoadFromCSVFile(BuildFilename(Now));
end;

Luckie 22. Jan 2020 11:53

AW: TStringlist wieder mit Trennzeichen speichern
 
In wie fern löst das sein Problem?

einbeliebigername 22. Jan 2020 12:21

AW: TStringlist wieder mit Trennzeichen speichern
 
Hallo,

man kann das auch komplizierter machen als es ist.
Delphi-Quellcode:
program Dp203164Project1;
{$APPTYPE CONSOLE}
uses
  System.SysUtils,
  System.Classes;
var
  vSl: TStringList;
  vI: Integer;
begin
  vSl:= TStringList.Create;
  try
    vSl.LineBreak:= ';';
    vSl.LoadFromFile('Test1.txt');
    Writeln('vSl.Count: '+ vSl.Count.ToString);
    for vI:= 0 to vSl.Count- 1 do
      Writeln('vSl['+ vI.ToString+ ']: '+ vSl[vI]);
    vSl.delete(2);
    vSl.delete(3);
    vSl.Move(1,0);
    vSl.insert(1,'10');
    vSl.Move(3,2);
    vSl.insert(3,'1');
    vSl.insert(4,'1');
    vSl.insert(5,' ');
    vSl.SaveToFile('Test2.txt');
  finally
    vSl.Free;
  end;
  Readln;
end.
Mit dem Inhalt
Code:
0193433020;2301000953;CNC-DB;3302060000;drehen01;300;;;;
ohne Enter in Test1.txt gibt es die Ausgabe:
Code:
vSl.Count: 9
vSl[0]: 0193433020
vSl[1]: 2301000953
vSl[2]: CNC-DB
vSl[3]: 3302060000
vSl[4]: drehen01
vSl[5]: 300
vSl[6]:
vSl[7]:
vSl[8]:
und den Inhalt
Code:
2301000953;10;3302060000;1;1; ;0193433020;300;;;;
ohne Enter in Test2.txt. Noch nicht ganz was der TE will. Das liegt aber an:
Delphi-Quellcode:
    vSl.delete(2);
    vSl.delete(3);
    vSl.Move(1,0);
    vSl.insert(1,'10');
    vSl.Move(3,2);
    vSl.insert(3,'1');
    vSl.insert(4,'1');
    vSl.insert(5,' ');


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:45 Uhr.
Seite 1 von 3  1 23   

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf