AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi geöffnete CSV bearbeiten

geöffnete CSV bearbeiten

Offene Frage von "Elliotx9"
Ein Thema von Elliotx9 · begonnen am 19. Aug 2007 · letzter Beitrag vom 20. Aug 2007
Antwort Antwort
Elliotx9

Registriert seit: 17. Aug 2007
3 Beiträge
 
#1

geöffnete CSV bearbeiten

  Alt 19. Aug 2007, 16:40
Datenbank: delphi • Version: 5 • Zugriff über: ODBC
Hallo zusammen,

Ich habe mal eine Frage zur Überprüfung von CSV-Dateien. Ich würde gerne eine geöffnete CSV-Datei nach bestimmten Kriterien (z.B. Parameterfolge '1234') zeilenweise untersuchen.
Wird in einer Zeile diese Parameterfolge nicht erfüllt, so soll eine Fehlermeldung in Form einer Liste mit entsprechenden Zeilennummern ausgegeben werden.

Vielleicht habt Ihr ja eine Idee, wie man das am Besten realisieren kann.


Hier ist erstmal der vorläufige Quellcode:

Delphi-Quellcode:
unit MainUnit;

interface

{$ifdef VER140}
  {$define DELPHI6_UP}
{$endif}
{$ifdef VER150}
  {$define DELPHI6_UP}
{$endif}
{$ifdef VER160}
  {$define DELPHI6_UP}
{$endif}
{$ifdef VER170}
  {$define DELPHI6_UP}
{$endif}
{$ifdef VER180}
  {$define DELPHI6_UP}
  {$define BDS2006_UP}
{$endif}

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

type
  TMainForm = class(TForm)
    TopPanel: TPanel;
    lbxRecords: TListBox;
    Splitter: TSplitter;
    lbxFields: TListBox;
    Label1: TLabel;
    FileEdit: TEdit;
    btnPickFile: TButton;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    stLineNo: TStaticText;
    stLineCount: TStaticText;
    stFieldCount: TStaticText;
    stFieldNo: TStaticText;
    gbParsing: TGroupBox;
    rbCustom: TRadioButton;
    rbCommaText: TRadioButton;
    rbDelimitedText: TRadioButton;
    Label6: TLabel;
    DelimEdit: TEdit;
    Label7: TLabel;
    QuoteEdit: TEdit;
    btnOpen: TButton;
    OpenDialog: TOpenDialog;
    NewlineEdit: TEdit;
    Label8: TLabel;
    cbEatWhitespace: TCheckBox;
    cbStrictDelimiter: TCheckBox;
    procedure btnPickFileClick(Sender: TObject);
    procedure btnOpenClick(Sender: TObject);
    procedure lbxRecordsClick(Sender: TObject);
    procedure lbxFieldsClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
    FDelim: String;
    FQuote: String;
    FNewline: String;
    procedure ResetDisplay;
    procedure ParseRecord;
    procedure UpdateFieldNo;
    function OptionToText(S: String): String;
    function TextToOption(S: String): String;
  public
    { Public declarations }
  published
    procedure ParseOptionChange(Sender: TObject);
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

uses llCSV;

function TMainForm.OptionToText(S: String): String;
var
  i: Integer;
begin
  Result := S;
  if (Length(S) = 1) then begin
    i := Ord(S[1]);
    if (i < 32) or (i > 127) then
      Result := Format('%.3d', [i]);
  end;
end;

function TMainForm.TextToOption(S: String): String;
var
  i: Integer;
begin
  Result := S;
  if Length(S) = 3 then begin
    i := StrToIntDef(S, 0);
    if (i mod 256 = i) and (Format('%.3d', [i]) = S) then
      Result := Chr(i);
  end;
end;

procedure TMainForm.FormShow(Sender: TObject);
begin
  {$ifndef DELPHI6_UP}
  rbDelimitedText.Enabled := False;
  {$endif}
  {$ifdef BDS2006_UP}
  cbStrictDelimiter.Enabled := not rbCustom.Checked;
  cbStrictDelimiter.Checked := lbxFields.Items.StrictDelimiter;
  {$else}
  cbStrictDelimiter.Enabled := False;
  {$endif}
  ResetDisplay;
  DelimEdit.Text := OptionToText(DefaultDelim);
  QuoteEdit.Text := OptionToText(DefaultQuote);
  NewlineEdit.Text := OptionToText(DefaultNewline);
  // Associate me with CSV files if you don't have Excel!
  if ParamCount > 0 then begin
    FileEdit.Text := ParamStr(1);
    btnOpenClick(Sender);
  end;
end;

procedure TMainForm.ResetDisplay;
begin
  lbxRecords.Clear;
  lbxFields.Items.Text := 'Copyright ©2007 Ray Marron - www.raymarron.com';
  stLineCount.Caption := '-';
  stLineNo.Caption := '-';
  stFieldCount.Caption := '-';
  stFieldNo.Caption := '-';
  stFieldCount.Color := clBtnFace;
end;

procedure TMainForm.btnPickFileClick(Sender: TObject);
begin
  if FileEdit.Text <> 'then
    OpenDialog.InitialDir := ExtractFileDir(FileEdit.Text);
  if OpenDialog.Execute then begin
    FileEdit.Text := OpenDialog.FileName;
    btnOpenClick(Sender);
  end;
end;

procedure TMainForm.btnOpenClick(Sender: TObject);
begin
  ResetDisplay;
  if FileEdit.Text = 'then
    Exit;
  if not FileExists(FileEdit.Text) then begin
    ShowMessage('File not found: ' + FileEdit.Text);
    Exit;
  end;
  lbxRecords.Items.LoadFromFile(FileEdit.Text);
  stLineCount.Caption := IntToStr(lbxRecords.Items.Count);
  if lbxRecords.Items.Count > 0 then begin
    lbxRecords.ItemIndex := 0;
    ParseOptionChange(Sender);
  end;
end;

procedure TMainForm.lbxRecordsClick(Sender: TObject);
begin
  ParseRecord;
end;

procedure TMainForm.UpdateFieldNo;
begin
  if lbxFields.ItemIndex >= 0 then
    stFieldNo.Caption := Format('%d (%d)',
      [lbxFields.ItemIndex + 1, Length(lbxFields.Items[lbxFields.ItemIndex])])
  else
    stFieldNo.Caption := '-';
end;

procedure TMainForm.lbxFieldsClick(Sender: TObject);
begin
  UpdateFieldNo;
end;

procedure TMainForm.ParseOptionChange(Sender: TObject);
begin
  DelimEdit.Enabled := not rbCommaText.Checked;
  QuoteEdit.Enabled := not rbCommaText.Checked;
  NewlineEdit.Enabled := rbCustom.Checked;
  cbEatWhitespace.Enabled := rbCustom.Checked;

  if DelimEdit.Text = 'then
    DelimEdit.Text := OptionToText(DefaultDelim);
  FDelim := TextToOption(DelimEdit.Text)[1];

  if QuoteEdit.Text = 'then
    QuoteEdit.Text := OptionToText(DefaultQuote);
  FQuote := TextToOption(QuoteEdit.Text)[1];

  if NewlineEdit.Text = 'then
    NewlineEdit.Text := OptionToText(DefaultNewline);
  FNewline := TextToOption(NewlineEdit.Text);

  {$ifdef DELPHI6_UP}
  lbxFields.Items.Delimiter := FDelim[1];
  lbxFields.Items.QuoteChar := FQuote[1];
  {$endif}

  {$ifdef BDS2006_UP}
  cbStrictDelimiter.Enabled := not rbCustom.Checked;
  lbxFields.Items.StrictDelimiter := cbStrictDelimiter.Checked;
  {$endif}

  ParseRecord;
end;

procedure TMainForm.ParseRecord;
var
  i: Integer;
  MultiLine, GoodData: Boolean;
begin
  stLineNo.Color := clBtnFace;
  stFieldCount.Color := clBtnFace;
  lbxFields.Items.BeginUpdate;
  try
    lbxFields.Items.Clear;
    i := lbxRecords.ItemIndex;
    if i < 0 then begin
      stFieldCount.Caption := '-';
      stFieldNo.Caption := '-';
      Exit;
    end;
    stLineNo.Caption := Format('%d (%d)', [i + 1, Length(lbxRecords.Items[i])]);
    if rbCustom.Checked then begin
      GoodData := True;
      MultiLine := False;
      repeat
        if not ParseCSVLine(lbxRecords.Items[i], lbxFields.Items,
                            MultiLine, FQuote[1], FDelim[1], FNewline,
                            cbEatWhitespace.Checked) then
          GoodData := False;
        Inc(i);
        if MultiLine then
          stLineNo.Color := clYellow; // Indicate a multi-line record with color
      until (not MultiLine) or (i = lbxRecords.Items.Count);
      if MultiLine or not GoodData then // If MultiLine is still true, we ran out of data!
        stFieldCount.Color := clRed; // Indicate bad data with color
    end else if rbCommaText.Checked then begin
      lbxFields.Items.CommaText := lbxRecords.Items[i];
    {$ifdef DELPHI6_UP}
    end else if rbDelimitedText.Checked then begin
      lbxFields.Items.DelimitedText := lbxRecords.Items[i];
    {$endif}
    end;
    if lbxFields.Items.Count > 0 then
      lbxFields.ItemIndex := 0;
  finally
    lbxFields.Items.EndUpdate;
  end;
  stFieldCount.Caption := IntToStr(lbxFields.Items.Count);
  UpdateFieldNo;
end;

end.


Vielen Dank schon einmal im voraus für alle konstruktiven Vorschläge.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: geöffnete CSV bearbeiten

  Alt 19. Aug 2007, 19:37
Vielleicht wäre der Einsatz eines CSV-Dataset sinnvoll
Markus Kinzler
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#3

Re: geöffnete CSV bearbeiten

  Alt 19. Aug 2007, 20:04
standardmässig öffnet delphi auch TP bei einen reset mit dem filemode 02 (read und write). wenn du ein CSV, welches bereits geöffnet ist, noch mal öffnen möchtest, musst du den filemode vor dem öffnen auf read OF_READ (= 0; definiert in der unit windows) setzen. dann sollte es klappen.

grüss und noch viel erfolg.
gg
  Mit Zitat antworten Zitat
Elliotx9

Registriert seit: 17. Aug 2007
3 Beiträge
 
#4

Re: geöffnete CSV bearbeiten

  Alt 20. Aug 2007, 12:22
Danke erstmal für Eure Antworten.

CSV-Dataset ist mir eher unbekannt, daher versuche ich das Problem mit Hilfe von TStringGrid anstatt mit 'ListBox' zu lösen. Dann lassen sich vielleicht die einzelnen Zellkoordinaten besser miteinander vergleichen, überprüfen und zusammenfassend auswerten. Die Frage ist nur, wie ich eines der StringGrid-Fenster als .txt - Datei abspeichern kann.
Wenn sonst noch jemanden etwas einfällt, so kann er dies natürlich gerne mitteilen (Thread ist also noch nicht geschlossen...).

Wenn ich irgendwann mal fertig bin stelle ich sonst auch mal den kompletten Quellcode rein.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: geöffnete CSV bearbeiten

  Alt 20. Aug 2007, 12:25
Ein CSV-DataSet ist eine Komponente, die eine CSV-Datei als ein DataSet kapselt. So kann man wie auf eine Datenbank zugreifen (.First, .Next, .Locate, .Lookup, FieldByName, ...)
Markus Kinzler
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: geöffnete CSV bearbeiten

  Alt 20. Aug 2007, 12:38
Hallo,

TStringList hat eine LoadFromFile Methode,
du musst nur den Separator richtig einstellen.

Und zum Speichern aus einem StringGrid kannst du du einfach TextFile benutzen.

Delphi-Quellcode:
var
  TxtFile: TextFile;
  sLine: String;
  iCol, iRow: Integer;
begin
  AssignFile(TxtFile, 'c:\bla.txt');
  Rewrite(TxtFile);

// try finally selber machen

  for iRow:= 0 to StrGrid.WorCount-1 do
  begin
    sLine:= '';

    for iCol:= 0 to StrGrid.ColCount-1 do
    begin
      if iCol>0 then sLine:= sLine+';';
      sLine:= sLine+StrGid.Cells[iCol,iRow];
    end;
   
    Writeln(TxtFile, sLine);
  end;

  CloseFile(TxtFile);
end;

Heiko
Heiko
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 03:10 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