AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte CSVViewer - Zum Betrachten von CSV-Dateien
Thema durchsuchen
Ansicht
Themen-Optionen

CSVViewer - Zum Betrachten von CSV-Dateien

Ein Thema von Luckie · begonnen am 14. Feb 2011 · letzter Beitrag vom 12. Nov 2013
Antwort Antwort
Seite 3 von 4     123 4      
Benutzerbild von Luckie
Luckie
Registriert seit: 29. Mai 2002
Nichts großes, weltbewegendes. Nur ein kleines Programm, um CSV-Dateien betrachten zu können, ohne dass man immer gleich Excel oder OpenOffice starten muss. So was wollte ich schon immer mal für die Backupdateien meiner Adressdatenbank machen und jetzt habe ich es gemacht. Es war eigentlich nur für mich zu privat Zwecken gedacht, aber eventuell findet es ja noch jemand anders nützlich, wenn nicht das Programm, dann vielleicht den Code, obwohl auch dieser war in seiner Grundform in zwanzig Minuten hingehackt.

Das Programm sollte selbsterklärend sein. Mit einem Rechtsklick auf den Listview öffnet sich ein Kontextmenü, mit dem man entweder die eine Zelle/Feld in die Zwischenablage kopieren kann oder die ganze Zeile.
Miniaturansicht angehängter Grafiken
csvviewer.jpg  
Angehängte Dateien
Dateityp: zip CSVViewer.zip (288,8 KB, 297x aufgerufen)
Ein Teil meines Codes würde euch verunsichern.
 
Benutzerbild von Sir Rufo
Sir Rufo

 
Delphi 10 Seattle Enterprise
 
#21
  Alt 14. Feb 2011, 22:58
Ihr macht mir echt Spaß!

Aus einem kleinen CSVViewer flugs ein Monster mit DatenbankTrallala gemacht

Und Tschüss

Wie sehen bei dir denn kleine Programme aus?
Einzeiler mit Hallo Welt?

Und alles andere ist dann schon Overkill?
  Mit Zitat antworten Zitat
Benutzerbild von vergessen
vergessen

 
Delphi 5 Professional
 
#22
  Alt 14. Feb 2011, 23:15
Ihr macht mir echt Spaß!

Aus einem kleinen CSVViewer flugs ein Monster mit DatenbankTrallala gemacht

Und Tschüss

Wie sehen bei dir denn kleine Programme aus?
Einzeiler mit Hallo Welt?

Und alles andere ist dann schon Overkill?
Mit D7pe jedenfalls ohne Datenbankkram...
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

 
Delphi XE3 Enterprise
 
#23
  Alt 14. Feb 2011, 23:16
@vergessen
Monster?
Das ist der unaufwändigste und naheliegenste Weg.
Thomas Wassermann H₂♂
  Mit Zitat antworten Zitat
Benutzerbild von vergessen
vergessen

 
Delphi 5 Professional
 
#24
  Alt 14. Feb 2011, 23:23
@vergessen
Monster?
Das ist der unaufwändigste und naheliegenste Weg.
Was denn, Deiner Meinung nach?

Von D7pe mal kurz auf D7pro aufrüsten?

Luckies Original-Source lief mit ein paar kleinen Änderungen auch mit D7pe.

Mei mei oh mei...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

 
Delphi 10 Seattle Enterprise
 
#25
  Alt 14. Feb 2011, 23:26
Kann aber nicht alle CSV Dateien nach RFC 4180 korrekt verarbeiten.

Wenn du das nachbauen möchtest, dann hast du schon ein kleineres Monster.

Für mich zählt neben DRY auch DRW (Don't Reinvent Wheels)
  Mit Zitat antworten Zitat
Benutzerbild von vergessen
vergessen

 
Delphi 5 Professional
 
#26
  Alt 14. Feb 2011, 23:46
Kann aber nicht alle CSV Dateien nach RFC 4180 korrekt verarbeiten.

Wenn du das nachbauen möchtest, dann hast du schon ein kleineres Monster.

Für mich zählt neben DRY auch DRW (Don't Reinvent Wheels)
Mangels DatenbankTrallala in D7pe muß ich wohl ein vorhandenes Rad neu erfinden

Sollte mit StringReplace wohl zu machen sein, denke ich mir einfach mal...

@Luckie: Unter welcher Lizenz ist/steht Dein "CSVViewer"-Sourcecode?

MfG
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

 
Delphi 10 Seattle Enterprise
 
#27
  Alt 14. Feb 2011, 23:54
Luckie hat ja (im Kern) eh "nur" die Methoden von TStringList benutzt.

Die kannst du aber nicht nehmen, weil die das nicht unterstützen.
Somit muss ein eigener Parser her, der sich aber in Grenzen hält, weil du eh nur auf nicht mal eine Handvoll Zeichen prüfen mußt.

Delimiter
Quotes
Zeilenende

Das sollte sich eigentlich gut bewerkstelligen lassen
  Mit Zitat antworten Zitat
Benutzerbild von vergessen
vergessen

 
Delphi 5 Professional
 
#28
  Alt 15. Feb 2011, 00:12
Die kannst du aber nicht nehmen, weil die das nicht unterstützen.
Ahjahhh. Danke für die Aufklärung!

Eine selbstgeschriebene Function reinwurschteln geht wohl neuerdings nicht mehr?

Ahjahhh. Danke für die Aufklärung!

mei oh mei oh mei!
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

 
Delphi 10 Seattle Enterprise
 
#29
  Alt 15. Feb 2011, 00:21
Eine selbstgeschriebene Function reinwurschteln geht wohl neuerdings nicht mehr?

Ahjahhh. Danke für die Aufklärung!

mei oh mei oh mei!
In TStringList? ... öh ... ja ... ist aber wohl mehr Aufwand als Nutzen, weil du eigenlich nix davon gebrauchen kannst ...
Das Problem ist, dass die TStringList eben stur mit dem Zeilenende arbeitet.

Eine CSV-Datei kann aber innerhalb eines Feldes auch Zeilenumbrüche beinhalten, und da macht die TStringList eben schlapp.

(Die TStringList ist auch nur für das Aufbrechen einer Zeile benutzt worden, nicht für die gesamte CSV-Datei als Ganzes)

Also eine eigene Klasse bauen (TCSVData) und parsen

Hab da mal was auf die Schnelle zusammengehackt:
Delphi-Quellcode:
unit CSVData;

interface

type
  TCSVData = class
  private
    FData : array of array of string;
    FDelim : Char;
    FQuote : Char;
    function GetRows : Integer;
    function GetCols : Integer;
    function GetCell( Row, Col : Integer ) : string;
    procedure SetCell( Row, Col : Integer; const Value : string );
  public
    destructor Destroy; override;
    procedure LoadFromFile( const FileName : string );
    property Cell[Row, Col : Integer] : string
      read GetCell
      write SetCell;
    property Rows : Integer
      read GetRows;
    property Cols : Integer
      read GetCols;
    property Delim : Char
      read FDelim
      write FDelim;
    property Quote : Char
      read FQuote
      write FQuote;
  end;

implementation

uses
  Classes;

{ TCSVData }

destructor TCSVData.Destroy;
begin
  SetLength( FData, 0, 0 );
  inherited;
end;

function TCSVData.GetCell( Row, Col : Integer ) : string;
begin
  Result := FData[Row, Col];
end;

function TCSVData.GetCols : Integer;
begin
  if Rows > 0
  then
    Result := Length( FData[0] )
  else
    Result := 0;
end;

function TCSVData.GetRows : Integer;
begin
  Result := Length( FData );
end;

procedure TCSVData.LoadFromFile( const FileName : string );
var
  Data : TStrings;
  Val : string;
  MyChar : Char;
  LastChar : Char;
  QuotePart : Boolean;
  Col : Integer;
  Row : Integer;
  MaxCol : Integer;
begin
  Data := TStringList.Create;
  try
    Data.LoadFromFile( FileName );

    LastChar := #0;
    QuotePart := False;
    Val := '';
    MaxCol := 0;
    Col := 0;
    Row := 0;

    // Jedes Zeichen durchlaufen
    for MyChar in Data.Text do
      begin
        if ( MyChar = Quote )
        then
          begin
            // QuotePart wechselt den Status
            QuotePart := not QuotePart;

            // Befinden wir uns im QuotePart und das letzte Zeichen
            // war das Quote-Zeichen, dann handelt es sich um eine
            // Verdoppelung und wir hängen das Quote-Zeichen an
            // den Puffer
            if QuotePart and ( LastChar = Quote )
            then
              Val := Val + Quote;
          end
        else if not QuotePart and ( MyChar = Delim )
        then
          begin
            // Sind noch nicht genug Zeilen da ...
            if high( FData ) < Row + 1
            then
              // ... dann auf Verdacht schon mal 10 hinzufügen
              SetLength( FData, Row + 10 );
            // Sind noch nicht genug Spalten da ...
            if high( FData[Row] ) < Col + 1
            then
              // ... dann auf Verdacht schon mal 10 hinzufügen
              SetLength( FData[Row], Col + 10 );
            // Wert eintragen
            FData[Row, Col] := Val;
            // Puffer leeren
            Val := '';
            // Spalte hochzählen
            Inc( Col );
          end
        else if not QuotePart and ( ( MyChar = #13 ) or ( MyChar = #10 ) )
        then
          begin
            // Haben wir CR LF gefunden ...
            if ( MyChar = #10 ) and ( LastChar = #13 )
            then
              begin
                // Sind noch nicht genug Zeilen da ...
                if high( FData ) < Row + 1
                then
                  // ... dann auf Verdacht schon mal 10 hinzufügen
                  SetLength( FData, Row + 10 );
                // Die Anzahl der Spalten steht jetzt fest
                SetLength( FData[Row], Col + 1 );
                // MaxCol merken
                if Col > MaxCol
                then
                  MaxCol := Col;
                // Wert eintragen
                FData[Row, Col] := Val;
                // Puffer leeren
                Val := '';
                // Zeile hochzählen
                Inc( Row );
                // Neue Zeile => erste Spalte
                Col := 0;
              end;
          end
        else
          // Das aktuelle Zeichen an den Puffer hängen
          Val := Val + MyChar;
        // Das letzte Zeichen merken
        LastChar := MyChar;
      end;

    SetLength( FData, Row );

    // Das ist eigentlich nur notwendig, wenn die CSV-Datei falsch aufgebaut ist
    // und unterschiedliche Anzahl von Spalten in den Zeilen aufweist
    // Dieses ist allerdings nicht RFC-konform, aber wir wollen mal nicht so sein
    for Row := low( FData ) to high( FData ) do
      SetLength( FData[Row], MaxCol + 1 );

  finally
    Data.Free;
  end;
end;

procedure TCSVData.SetCell( Row, Col : Integer; const Value : string );
begin
  FData[Row, Col] := Value;
end;

end.

Geändert von Sir Rufo (15. Feb 2011 um 09:26 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

 
Delphi 2006 Professional
 
#30
  Alt 15. Feb 2011, 15:24
Danke. Aber im Moment hab eich andere Probleme. Mein Monitor hat schlapp gemacht und die Grafikkrate unterstützt die native Auflösung des neuen Monitores nicht. Jetzt muss auch erstmal eine neue Grafikkarte für günstig Geld her.

Aber ich denke heute Abend habe ich auch das Problem gelöst.
Michael
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


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 20:38 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