Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi csv Datei Import ClassHelper für TClientDataSet (https://www.delphipraxis.net/164041-csv-datei-import-classhelper-fuer-tclientdataset.html)

Uwe Raabe 19. Mai 2019 11:51

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Schokohase (Beitrag 1432529)
Mein Vorschlag ist es die Quote-Zeichen zu zählen, was immer passt.

Ich hatte da vor einiger Zeit mal einen class helper für
Delphi-Quellcode:
TTextReader
geschrieben, der das umsetzt:
Delphi-Quellcode:
type
  TTextReaderHelper = class helper for TTextReader
    function CharCount(const ALine: string; AChar: Char): Integer;
    procedure ReadQuotedLine(Target: TStrings);
  end;

function TTextReaderHelper.CharCount(const ALine: string; AChar: Char): Integer;
var
  C: Char;
begin
  result := 0;
  for C in ALine do begin
    if C = AChar then
      Inc(result);
  end;
end;

procedure TTextReaderHelper.ReadQuotedLine(Target: TStrings);
var
  line: string;
  line2: string;
  saveStrictDelimiter: Boolean;
begin
  line := ReadLine;
  if Odd(CharCount(line, Target.QuoteChar)) then begin
    { Eine ungerade Anzahl von Quotes bedeutet, daß der gequotete String mindestens einen Zeilenumbruch enthält.
      Wir hängen also die nachfolgenden Zeilen mit LineBreak an, bis eine weitere Zeile mit ungerader Anzahl
      Quotes kommt.
    }
    repeat
      line := line + sLineBreak;
      line2 := ReadLine;
      line := line + line2;
    until Odd(CharCount(line2, Target.QuoteChar));
  end;
  { Zeilenumrüche in line dürfen nicht in separate Einträge zerlegt werden! }
  saveStrictDelimiter := Target.StrictDelimiter;
  try
    Target.StrictDelimiter := True;
    Target.CommaText := line;
  finally
    Target.StrictDelimiter := saveStrictDelimiter;
  end;
end;

Blackpit 19. Mai 2019 11:53

AW: csv Datei Import ClassHelper für TClientDataSet
 
@Schokohase
Zitat:

Zitat von Schokohase
Du hast damit aber einen bösen Bug in deinem Code.

Da bin ich mal froh, das mir das TStringlist schon abnimmt ;)
Try it!

@Rollo62
Header wird erzeugt wenn nicht vorhanden

@Uwe Raabe
Auch elegant gelöst!
Ist aber nur ein Teil der Aufgabe;)

Schokohase 19. Mai 2019 13:55

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Blackpit (Beitrag 1432536)
@Schokohase
Zitat:

Zitat von Schokohase
Du hast damit aber einen bösen Bug in deinem Code.

Da bin ich mal froh, das mir das TStringlist schon abnimmt ;)
Try it!

I did
Code:
EStringListError: Listenindex außerhalb des gültigen Bereichs (3)
Meine Testdaten
Delphi-Quellcode:
'a;b;c;d' + sLineBreak + 
'a;"b;b";"c'#10'c";d'
oder als Text
Code:
a;b;c;d
a;"b;b";"c
c";d
Du solltest schon wissen, was dir TStringList abnimmt und vor allem ab wann.

Im Übrigen fängst du erst ab der 2. Zeile mit dem Import an - auch wenn der Parameter
Delphi-Quellcode:
FirstLineTitle
auf
Delphi-Quellcode:
false
steht.

Blackpit 19. Mai 2019 14:15

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Schokohase (Beitrag 1432538)
...Im Übrigen fängst du erst ab der 2. Zeile mit dem Import an - auch wenn der Parameter
Delphi-Quellcode:
FirstLineTitle
auf
Delphi-Quellcode:
false
steht.

Da hast du allerdings Recht.
Code:
If X=0 and (not FirstLineTitle)
Zitat:

Zitat von Schokohase (Beitrag 1432538)
Du solltest schon wissen, was dir TStringList abnimmt und vor allem ab wann.

Ich denke das tu ich schon, hast du meine Intention verstanden?
Und wie oft ist dir dein Beispiel im Alltag begegnet?
Wobei auch deine Konstellation unter meinen Voraussetzungen läuft.

Hmm:roll:

Schokohase 19. Mai 2019 14:26

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Blackpit (Beitrag 1432539)
Und wie oft ist dir dein Beispiel im Alltag begegnet?

Sagen wir so, das Beispiel ist gemäß RFC4180 gültig und sollte somit einwandfrei verarbeitet werden können. Mit dem Ansatz erspare ich mir nachher lästige und peinliche Diskussionen.

Ich kann es dir also nicht sagen, wie oft mein Beispiel im Alltag vorkommt, denn keiner bemerkt es, weil es anstandslos funktioniert.

Blackpit 19. Mai 2019 14:34

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Schokohase (Beitrag 1432540)

Sagen wir so, das Beispiel ist gemäß RFC4180 gültig und sollte somit einwandfrei verarbeitet werden können. Mit dem Ansatz erspare ich mir nachher lästige und peinliche Diskussionen.

Schön das du es erwähnst:
Zitat:

Zitat von https://tools.ietf.org/html/rfc4180
6. Fields containing line breaks (CRLF), double quotes, and commas
should be enclosed in double-quotes.

entspricht somit nicht der Spezi ;)

Schokohase 19. Mai 2019 15:01

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Blackpit (Beitrag 1432541)
Zitat:

Zitat von Schokohase (Beitrag 1432540)

Sagen wir so, das Beispiel ist gemäß RFC4180 gültig und sollte somit einwandfrei verarbeitet werden können. Mit dem Ansatz erspare ich mir nachher lästige und peinliche Diskussionen.

Schön das du es erwähnst:
Zitat:

Zitat von https://tools.ietf.org/html/rfc4180
6. Fields containing line breaks (CRLF), double quotes, and commas
should be enclosed in double-quotes.

entspricht somit nicht der Spezi ;)

Also mein Beispiel mit den 3 Zeilen beinhaltet ZWEI Datenzeilen.
Die zweite Zeile sieht in Delphi-String-Schreibweise so aus
Delphi-Quellcode:
'a;"b;b";"c'#13#10'c";d'
.
(aber auch so ist es gültig
Delphi-Quellcode:
'a;"b;b";"c'#10'c";d'
)

Sieht du jetzt was da zwischen den Quote-Zeichen steht?

Das ist 100% gültig nach RFC4180.

PS
Wenn du wissen möchtest, was so alles RFC4180 konform ist, dann kannst du gerne deine Dateien mit dem Webdienst http://csvlint.io/ überprüfen lassen.

Allerdings wird dort zwingend das Komma als Feld-Trenner gefordert.

Und diese Datei
Code:
a,b,c,d
aa,"b,b","c
c",dd
findet der total gut (was auch zu erwarten war, weil RFC4180 konform)

Blackpit 19. Mai 2019 16:01

AW: csv Datei Import ClassHelper für TClientDataSet
 
Du sprichst immer von Dateien, könntest du mir das Beispiel als Datei zur Verfügung stellen?
Hab keine Lust dafür zu coden und möchte auch keinen Hex-Editor dafür bemühen.

Schokohase 19. Mai 2019 16:12

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Blackpit (Beitrag 1432548)
Du sprichst immer von Dateien, könntest du mir das Beispiel als Datei zur Verfügung stellen?
Hab keine Lust dafür zu coden und möchte auch keinen Hex-Editor dafür bemühen.

Du meinst du schaffst es nicht mein Text-Beispiel per Copy-Paste in einen Text-Editor zu bringen und mit dem Namen "test.csv" zu speichern?

Blackpit 19. Mai 2019 17:05

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Schokohase (Beitrag 1432550)
...
Du meinst du schaffst es nicht mein Text-Beispiel per Copy-Paste in einen Text-Editor zu bringen und mit dem Namen "test.csv" zu speichern?

Nein, wenn du es selbst mal versucht hättest, würdest du nur zwei CrLf sehen.
Selbst mit Notepad+ gelingt es mir nicht, sonst würde ich nicht danach fragen.

Schokohase 19. Mai 2019 18:59

AW: csv Datei Import ClassHelper für TClientDataSet
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ohne Worte

Obwohl, das ist jetzt Copy-Paste der Beispiel-Daten aus dem Beitrag #47 in Visual Studio Code eingefügt und als CSV-Datei abgespeichert.

Währenddessen habe ich auch noch ein- und ausgeatmet.

Blackpit 21. Mai 2019 20:49

AW: csv Datei Import ClassHelper für TClientDataSet
 
@Schokohase
Ich bin ja froh das deine Datei auch nicht die Anforderung erfüllt
Zitat:

Zitat von Schokohase
Meine Testdaten
Delphi-Quellcode:
'a;b;c;d' + sLineBreak + 
'a;"b;b";"c'#10'c";d'

mit dieser Version wird aber auch deine Datei eingelesen
Delphi-Quellcode:
procedure TClientDataSetCsvClassHelper.LoadFromFile;
var
  myString :Variant;
  slFile :TStringList;
  slRow :TStringList;
  x,i,j :Integer;
  myPos :Integer;
  myFields :Integer;
  cntFields :Integer;
begin
  slFile := TStringList.Create;
  slRow := TStringList.Create;
  try
    myPos := 0;
    slRow.Delimiter := Delimiter;
    slRow.QuoteChar := QuoteChar;
    slRow.StrictDelimiter := True;
    slFile.StrictDelimiter := True;
    slFile.LoadFromFile( Filename );

      // ClientDataset Initialisieren
    if slFile.Count > 0 then
    begin
      Active := False;
      for x := 0 to slFile.Count - 1 do
      begin
        myString := '';
        if (x = 0) then
        begin
          myPos := x;
            // Build Header for DS
          slRow.DelimitedText := slFile[0];
          if FirstLineTitle then myFields := slRow.Count else
           begin
           if (length( slFile[0] )-
              length( stringreplace( slFile[0], QuoteChar,'',[rfreplaceall, rfIgnoreCase])) mod 2 = 0) then
           myFields := length( slFile[0] )-
              length( stringreplace( slFile[0], Delimiter,'',[rfreplaceall, rfIgnoreCase]))
           else myFields := slRow.Count;
          FieldDefs.Clear;
          for i := 0 to myFields - 1 do
            begin
              FieldDefs.Add( Format( 'Field%d',[i]), ftWideString, StringLength );
            end;
          end;
          if FirstLineTitle then
          begin
          for i := 0 to myFields - 1 do
              FieldDefs.Add( slRow[i], ftWideString, StringLength );
          end;
          CreateDataSet;
          Active := True;
          myString := slFile[myPos];
        end;
        begin
        if (x=0) and FirstLineTitle then inc( myPos );
        if myPos = slFile.Count then break;
        myString := slFile[myPos];
        cntFields := length( myString )-
              length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
          while cntFields <= (myFields-1) do
          if FirstLineTitle and (cntFields < (myFields-1)) then
            begin
              inc( myPos );
              myString := myString+slFile[myPos];
              cntFields := length( myString )-
                length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
            end
            else
            if not FirstLineTitle and (x <> 0) then
            begin
              inc( myPos );
              myString := slFile[myPos];
             if (length( myString )-
                length( stringreplace( myString, QuoteChar,'',[rfreplaceall, rfIgnoreCase])) mod 2 <> 0) then
                begin
                myString := slFile[myPos-1]+myString;
                cntFields := length( myString )-
                  length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
                end
             else
                cntFields := length( myString )-
                  length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
            end
            else break;
        end;
          // fill TClientDataset
        DisableControls;
        begin
          slRow.DelimitedText := myString;
          Append;
          for j := 0 to slRow.Count - 1 do
          begin
            Fields[j].AsString := slRow[j];
          end;
          Post;
        end;
        EnableControls;
        inc( myPos );
      end;
    end;
  finally
    slFile.Free;
    slRow.Free;
  end;
end;

Blackpit 22. Mai 2019 17:16

AW: csv Datei Import ClassHelper für TClientDataSet
 
Ich gehe davon aus, das dieser Code nun fast RFC-konform ist (noch nicht ganz, da die Feldermittlung ohne FirstTitleLine noch Optimierungsbedarf hat).
Eine Textdatei mit CrLF und LF kommt einem im Alltag nicht unter, außer vielleicht zu Ostern:wink:

Schokohase 22. Mai 2019 17:48

AW: csv Datei Import ClassHelper für TClientDataSet
 
Erkläre doch bitte, warum meine Testdaten nicht RFC konform sein sollten.

Wenn Daten aus einem System (Datenbank) exportiert werden, dann können sich wenigstens meine Kunden darauf verlassen, dass die Daten unverändert in der CSV Datei landen. Und wenn dort nur ein CR oder LF enthalten ist, dann kommt auch nur das heraus - und zwar 24 Stunden an allen 7 Tagen jeder Woche.

Der Zeilenumbruch mit CRLF ist Teil der Struktur und nicht der Daten.

Ich denke aber wir haben eine unterschiedliche Lesart der RFC. Meine deckt sich mit dem größten Teil der Entwickler und deine ... ist deine Sache.

p80286 23. Mai 2019 11:24

AW: csv Datei Import ClassHelper für TClientDataSet
 
https://tools.ietf.org/html/rfc4180

Ich vermute das #10 wird von Blackpit mißinterpretiert.

Gruß
K-H

Blackpit 23. Mai 2019 16:01

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von p80286 (Beitrag 1432934)
https://tools.ietf.org/html/rfc4180

Ich vermute das #10 wird von Blackpit mißinterpretiert.

Gruß
K-H

Dann klärt mich doch bitte auf, bevor wir weiter aneinander vorbeireden.
Das als Grundlage:
Zitat:

Zitat von http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/System_sLineBreak.html
Windows systems define sLineBreak as a combination of carriage return (#13) and line feed (#10).
Linux systems define sLineBreak as simply a line feed (#10).
It is preferable to use this constabnt rather than hard code #13#10 or #10 (as appropriate) to move to a new line in a text output.

und ergänzt:
Apple systems define sLineBreak as simply a carriage return (#13).

Gruß
BP

MaBuSE 23. Mai 2019 17:35

AW: csv Datei Import ClassHelper für TClientDataSet
 
Die ganze Diskussion ist hinfällig, da es keine einheitliche CSV Format gibt.
Zitat:

Zitat von Wikipedia
Ein allgemeiner Standard für das Dateiformat CSV existiert nicht, jedoch wird es im RFC 4180 grundlegend beschrieben

Diese Beschreibung ist aber nur eine mögliche. Nach der Ansi Norm sind *.csv Dateien in unserem Sprachraum mit einem Semikolon getrennt.
Excel verwendet z.B. diese Ansi Norm. Mach mal einen Doppelklick auf eine mit Komma getrennte csv Datei. ;)
Es macht also keinen Sinn hier über Implementierungsdetails streiten.

Folgendes Beispiel ist auch NICHT rfc konform:
Code:
MaBuSE,"Hauptstraße 5",12345,Musterstadt
(Das "ß" ist nicht erlaubt.)

Das Zeilenwechsel Problem ist ja auch kein CSV spezifisches Problem. Das gibt es grundsätzlich beim Austausch von Textdateien zwischen PC <-> Unix <-> alte Mac.

Ein Zeilenwechsel kann sein #13#10, #10 oder auch #13
Letzteres war früher bei Macs, ist aber mittlerweile unüblich.

TStringList kann auf PC vernünftig nur mit #13#10 umgehen. Je nachdem wie man die Daten zuweist, wird es auch nach #13#10 umgewandelt oder nicht. :shock:
Das ist aber auch schon ewig so.

Ich habe das nach dem Laden/Zuweisen immer mit einem
Delphi-Quellcode:
sl.Text := sl.Text;
gelöst. Damit werden alle #13 und #10 zu #13#10 umgewandelt.

Hier zum Testen: (Leeres Form mit einem TButton und 5 TMemo)
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add('Aa,Bb');
  sl.Add('"A'#13#10'a",Bb');
  sl.Add('"A'#10'a",Bb');
  sl.Add('"A'#13'a",Bb');
  Memo1.Lines.Text := sl.Text; // mit Umwandlung von #13 und #10 nach #13#10 
  Memo2.Lines.Add(sl.Text);    // ohne Umwandlung
  Memo3.Lines.Text := s2hex(Memo1.Lines.Text);
  Memo4.Lines.Text := s2hex(Memo2.Lines.Text);
  Memo5.Lines.Text := s2Hex(sl.Text);
end;

function TForm1.s2hex(s: string): string;
var
  i: Integer;
begin
  for i := 1 to length(s) do
   begin
     Result := Result + IntToHex(Ord(s[i]),2) + #32;
   end;
end;
-> so sieht es dann aus:

Code:
Memo1:
Aa,Bb
"A
a",Bb
"A
a",Bb
"A
a",Bb

Memo2:
Aa,Bb
"A
a",Bb
"Aa",Bb
"Aa",Bb

41 61 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41    0A 61 22 2C 42 62 0D 0A 22 41 0D   61 22 2C 42 62 0D 0A       // sl.Text
41 61 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A       // sl.Text nach Text := Text
41 61 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A       // Memo1.Lines.Text
41 61 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41    0A 61 22 2C 42 62 0D 0A 22 41 0D   61 22 2C 42 62 0D 0A 0D 0A // Memo2.Lines.Text mit zusätzlichem #13#10 am Ende (durch das Add)

p80286 23. Mai 2019 20:12

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von Blackpit (Beitrag 1432766)
@Schokohase
Ich bin ja froh das deine Datei auch nicht die Anforderung erfüllt
Zitat:

Zitat von Schokohase
Meine Testdaten
Delphi-Quellcode:
'a;b;c;d' + sLineBreak + 
'a;"b;b";"c'#10'c";d'


Code:
Zeile1: a;b;c;d
Zeile2: a;"b;b";"c#10c";d

Zeile1: a b     c       d
Zeile2: a "b;b" "c#10c" d
Beachte die " mit denen die Felder die speziellen Zeichen einrahmen.
Speziell sind in diesem Fall das ; und #10

Gruß
K-H

MaBuSE 24. Mai 2019 08:44

AW: csv Datei Import ClassHelper für TClientDataSet
 
Ich wollte mit meinem Beitrag eigentlich die unsinnige Diskussion über #13#10 und #10 beenden.

Falls ihr es nicht gemerkt habt. Das ist ein Code-Bibliothek Beitrag. Hier sollte nicht so viel diskutiert werden.

Macht einfach nach dem:
Delphi-Quellcode:
slFile.LoadFromFile( Filename );
ein
Delphi-Quellcode:
slFile.Text := slFile.Text
und beendet diese Diskussion hier.
(Oder macht einen eigenen Thread mit dem Titel "unsinnige Diskussion über #13#10 und #10 im Kontext des rfc4180" außerhalb der Code-Library auf.)
Danke

Blackpit 24. Mai 2019 16:33

AW: csv Datei Import ClassHelper für TClientDataSet
 
Zitat:

Zitat von MaBuSE (Beitrag 1433023)
...
Falls ihr es nicht gemerkt habt. Das ist ein Code-Bibliothek Beitrag. Hier sollte nicht so viel diskutiert werden.
...

Sehe ich auch so, deshalb hier noch ein verbesserter Vorschlag unter Berücksichtigung von Schokohase und Uwes Empfehlung Odd vs. mod 2
Delphi-Quellcode:
procedure TClientDataSetCsvClassHelper.LoadFromFile;
var
  myString :Variant;
  slFile :TStringList;
  slRow :TStringList;
  x,i,j :Integer;
  myPos :Integer;
  myFields :Integer;
  cntFields :Integer;
begin
  slFile := TStringList.Create;
  slRow := TStringList.Create;
  try
    myPos := 0;
    slRow.Delimiter := Delimiter;
    slRow.QuoteChar := QuoteChar;
    slRow.StrictDelimiter := True;
    slFile.StrictDelimiter := True;
    slFile.LoadFromFile( Filename );

      // ClientDataset Initialisieren
    if slFile.Count > 0 then
    begin
      Active := False;
      for x := 0 to slFile.Count - 1 do
      begin
        myString := '';
        if (x = 0) then
        begin
          myPos := x;
            // Build Header for DS
          slRow.DelimitedText := slFile[0];
          if FirstLineTitle then myFields := slRow.Count else
           begin
           cntFields := 0;
           myString := slFile[myPos];
           if Odd(length( myString )-
                length( stringreplace( myString, QuoteChar,'',[rfreplaceall, rfIgnoreCase]))) then
             while Odd(length( myString )-
                length( stringreplace( myString, QuoteChar,'',[rfreplaceall, rfIgnoreCase]))) do
             begin
             Inc(mypos);
             myString := myString+slFile[myPos];
             cntFields := length( myString )-
                length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
             end
           else myFields := slRow.Count;
          if cntFields > 0 then myFields := cntFields + 1;
          FieldDefs.Clear;
          for i := 0 to myFields - 1 do
            begin
              FieldDefs.Add( Format( 'Field%d',[i]), ftWideString, StringLength );
            end;
          end;
          if FirstLineTitle then
          begin
          for i := 0 to myFields - 1 do
              FieldDefs.Add( slRow[i], ftWideString, StringLength );
          end;
          CreateDataSet;
          Active := True;
          cntFields := 0;
        end;
        begin
        if (x=0) and FirstLineTitle then inc( myPos );
        if myPos = slFile.Count then break;
        If myString = '' then myString := slFile[myPos];
        cntFields := length( myString )-
              length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
          while cntFields <= (myFields-1) do
          if FirstLineTitle and (cntFields < (myFields-1)) then
            begin
              inc( myPos );
              myString := myString+slFile[myPos];
              cntFields := length( myString )-
                length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
            end
            else
            if not FirstLineTitle and (x <> 0) then
            begin
            If myString = '' then myString := slFile[myPos];
            while Odd(length( myString )-
              length( stringreplace( myString, QuoteChar,'',[rfreplaceall, rfIgnoreCase]))) do
             if Odd(length( myString )-
                (length( stringreplace( myString, QuoteChar,'',[rfreplaceall, rfIgnoreCase])))) then
                begin
                inc( myPos );
                myString := myString+slFile[myPos];
                cntFields := length( myString )-
                  length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
                end
             else
                cntFields := length( myString )-
                  length( stringreplace( myString, Delimiter,'',[rfreplaceall, rfIgnoreCase]));
            end
            else
            break;
        end;
          // fill TClientDataset
        DisableControls;
        begin
          slRow.DelimitedText := myString;
          Append;
          for j := 0 to slRow.Count - 1 do
          begin
            Fields[j].AsString := slRow[j];
          end;
          Post;
        end;
        EnableControls;
        inc( myPos );
      end;
    end;
  finally
    slFile.Free;
    slRow.Free;
  end;
end;
HTH

Blackpit 24. Mai 2019 16:38

AW: csv Datei Import ClassHelper für TClientDataSet
 
Doppelpost bitte löschen

Blackpit 24. Mai 2019 16:43

AW: csv Datei Import ClassHelper für TClientDataSet
 
Doppelpost bitte löschen


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:28 Uhr.
Seite 2 von 2     12   

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