AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi csv Datei Import ClassHelper für TClientDataSet
Thema durchsuchen
Ansicht
Themen-Optionen

csv Datei Import ClassHelper für TClientDataSet

Ein Thema von MaBuSE · begonnen am 26. Okt 2011 · letzter Beitrag vom 24. Mai 2019
Antwort Antwort
Seite 1 von 2  1 2      
Blackpit

Registriert seit: 27. Feb 2019
77 Beiträge
 
#1

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 19. Mai 2019, 17:05
...
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.
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#2

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 19. Mai 2019, 18:59
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.
Angehängte Dateien
Dateityp: zip test1.csv.zip (623 Bytes, 16x aufgerufen)

Geändert von Schokohase (19. Mai 2019 um 19:02 Uhr)
  Mit Zitat antworten Zitat
Blackpit

Registriert seit: 27. Feb 2019
77 Beiträge
 
#3

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 21. Mai 2019, 20:49
@Schokohase
Ich bin ja froh das deine Datei auch nicht die Anforderung erfüllt
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;

Geändert von Blackpit (21. Mai 2019 um 21:30 Uhr)
  Mit Zitat antworten Zitat
Blackpit

Registriert seit: 27. Feb 2019
77 Beiträge
 
#4

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 22. Mai 2019, 17:16
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

Geändert von Blackpit (22. Mai 2019 um 17:44 Uhr)
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#5

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 22. Mai 2019, 17:48
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.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#6

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 23. Mai 2019, 11:24
https://tools.ietf.org/html/rfc4180

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

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Blackpit

Registriert seit: 27. Feb 2019
77 Beiträge
 
#7

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 23. Mai 2019, 16:01
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 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
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#8

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 23. Mai 2019, 20:12
@Schokohase
Ich bin ja froh das deine Datei auch nicht die Anforderung erfüllt
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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector

Geändert von p80286 (23. Mai 2019 um 20:21 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.840 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 24. Mai 2019, 08:44
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: slFile.LoadFromFile( Filename ); ein 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
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat
Blackpit

Registriert seit: 27. Feb 2019
77 Beiträge
 
#10

AW: csv Datei Import ClassHelper für TClientDataSet

  Alt 24. Mai 2019, 16:33
...
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
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:04 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