Einzelnen Beitrag anzeigen

Popov
(Gast)

n/a Beiträge
 
#3

AW: .csv Datei einlesen, analysieren und bearbeitet abspeichern.

  Alt 18. Apr 2015, 20:30
Dade, ich will es nicht beschwören, aber ich denke mir der Ordner "Software-Projekte der Mitglieder" ist eher dafür gedacht, dass Mitglieder ihre Projekte vorstellen können, weniger, dass einer Aufgaben aufgibt.

Da es aber nicht wirklich großes ist, habe ich schnell etwas zusammen getippt. Das Programm macht aus allen CSV Dateien in einem Ordner eine einzige große CSV-Datei.

Beim programmieren bemerkte ich, das die CSV Dateien zwischen den einzelnen Dateien Leerzeilen haben. Die machen TStringList Probleme und lassen sich nicht ohne Probleme beseitigen. Ich hatte aber keine große Lust eine elegante Lösung zu finden, also habe es so gelassen und nur die Fehler ignoriert. Dabei werden keine Daten verschluckt, die Fehler gibt es nur bei den Leeren Zeilen. Auch gibt es nur in der IDE die Fehlermeldungen. Als Exe gestartet werden sie still ignoriert.

Vorausgesetzt alle Dateien sind nach dem gleichen Muster, so gibt es oben 2 und unten 5 Zeilen die u. U. ignoriert werden können. Wenn ja, am Anfang der Prozedur die Anzahl eintragen.
Delphi-Quellcode:
uses
  FileCtrl;

procedure GetFiles(Path, ExtMask: String; List: TStrings);
const
  Attrib = faArchive or faReadOnly or faHidden or faSysFile;
var
  SR: TSearchRec;
begin
  Path := IncludeTrailingBackslash(Path);

  while Copy(ExtMask, 1, 1) = '.do Delete(ExtMask, 1, 1);

  if FindFirst(Path + '*.' + ExtMask, Attrib, SR) = 0 then
  repeat
    if SameText('.' + ExtMask, ExtractFileExt(SR.Name)) then
      List.Add(Path + SR.Name);
  until FindNext(SR) <> 0;
  SysUtils.FindClose(SR);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  VorneZeilenIgnorieren,
  HintenZeilenIgnorieren,
  i, k: Integer;
  Dir, OutPath: String;
  slDateiListe, slGrosseCsv, slEinzelCsv, slTemp: TStringList;
begin
  VorneZeilenIgnorieren := 0; //2;
  HintenZeilenIgnorieren := 0; //5;

  if not SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate, sdPrompt], 0) then
  begin
    MessageDlg('Kein Ordner ausgewählt.', mtError, [mbOk], 0);
    Exit;
  end;

  slDateiListe := TStringList.Create;
  try
    GetFiles(Dir, 'csv', slDateiListe);

    if slDateiListe.Count = 0 then
    begin
      MessageDlg('Kein Dateien gefunden.', mtError, [mbOk], 0);
      Exit;
    end
    else
      if MessageDlg(Format('%d CSV-Dateien gefunden. Weitermachen?', [slDateiListe.Count]),
        mtConfirmation, [mbYes, mbNo], 0) = mrNo then
          Exit;

    with SaveDialog1 do
    begin
      //Filter := 'CSV-Dateien|*.csv';
      if not Execute then
      begin
        MessageDlg('Vorgang Abgebrochen.', mtError, [mbOk], 0);
        Exit;
      end;
      OutPath := ChangeFileExt(FileName, '.csv');
      if FileExists(OutPath) then
        if MessageDlg('Datei bereits vorhanden. Überschreiben?.',
          mtConfirmation, [mbYes, mbNo], 0) = mrNo then
            Exit;;
    end;

    slGrosseCsv := TStringList.Create;
    try
      for i := 0 to slDateiListe.Count - 1 do
      begin
        slEinzelCsv := TStringList.Create;
        try
          slEinzelCsv.LoadFromFile(slDateiListe[i]);

          //In den csv-Dateien stimmt was nicht, zumindest kommt StringList
          //damit nicht klar. Schnelle Lösung. Es gibt fehlermeldungen, die
          //werden aber ignoriert.
          slTemp := TStringList.Create;
          try
            for k := 0 to slEinzelCsv.Capacity - 1 do
            try
              if Length(slEinzelCsv[k]) > 0 then
              slTemp.Add(slEinzelCsv[k]);
            except
              //Fehler Ignorieren
            end;
            slEinzelCsv.Text := slTemp.Text;
          finally
            slTemp.Free;
          end;

          //Entfernt vorne Zeilen, wenn gewünscht
          k := VorneZeilenIgnorieren;
          while (slEinzelCsv.Count > 0) and (k > 0) do
          begin
            slEinzelCsv.Delete(0);
            Dec(k);
          end;

          //Entfernt vorne Zeilen, wenn gewünscht
          k := HintenZeilenIgnorieren;
          while (slEinzelCsv.Count > 0) and (k > 0) do
          begin
            slEinzelCsv.Delete(slEinzelCsv.Count - 1);
            Dec(k);
          end;

          slGrosseCsv.AddStrings(slEinzelCsv);
        finally
          slEinzelCsv.Free;
        end;
      end;

      slGrosseCsv.SaveToFile(OutPath);
      MessageDlg('CSV-Dateien zusammengefügt und erfolgreich gespeichert ' +
        'unter: "' + OutPath + '".', mtInformation, [mbOk], 0);
    finally
      slGrosseCsv.Free;
    end;
  finally
    slDateiListe.Free;
  end;
end;
  Mit Zitat antworten Zitat