Delphi-PRAXiS
Seite 1 von 7  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   .csv Datei einlesen, analysieren und bearbeitet abspeichern. (https://www.delphipraxis.net/184749-csv-datei-einlesen-analysieren-und-bearbeitet-abspeichern.html)

Dade 18. Apr 2015 14:59

.csv Datei einlesen, analysieren und bearbeitet abspeichern.
 
HI Leute,
ich bin seit Tagen verzweifelt auf der Suche nach einer Möglichkeit, wie ich viele .csv - Dateien einlesen, einzelne Felder analysieren und alles dann als eine weitere Zeile in nur einer Excel Datei speichern kann.

Ich versuchte bereits Delphi zu lernen, da ich früher als Teenager mit Pascal programmierte, aber es hat sich doch sehr viel getan.


Ich hoffe sehr, dass ihr mir helfen könnt. Das wäre absolut toll.


Ich erkläre kurz worum es geht:
Ich bin an einem Projekt und nutze ein Programm, mit dem man Bilder ausmessen und Zellen zählen kann. Diese Ergebnisse werden mir als .csv - Datei ausgegeben. Insgesamt komme ich bestimmt am Ende auf über 1500 Dateien.
Diese sehen so aus:

--------------------
Annotations;;

Name;Perimeter (µm);Area (µm2)

LK_1_1_F_1;835,4;48705,5

LK_1_1_F_2;1142,7;93813,4

[.....ca. 20 Zeilen........]

LK_1_3;14272,3;7956108,4

;;

Distance measurement annotations;;

Length (µm);;

5,15;;

3,22;;

---------------------------------

Im Endeffekt müssen nun die Zahlen in bestimmter Art und Weise in der Excel Tabelle später stehen. Zusätzlich muss in der 1. Spalte jeweils der csv-Dateiname erscheinen (ist nämlich die Nummer) + die Angabe: LK_1_1_f_2 (als Beispiel von oben) analysiert werden nach "wie oft taucht "F" auf. Für jede .csv - Datei müssen die addiert und dann auch in einer Spalte stehen.

Ich habe hier vorher - Nachher + Erläuterungen hochgeladen: https://www.dropbox.com/sh/blbndn594...t68a?dl=0&s=sl

Alleine schaffe ich das nicht.

Gruß
Kai

khh 18. Apr 2015 16:17

AW: .csv Datei einlesen, analysieren und bearbeitet abspeichern.
 
naja, die einzelnen Files in ner Schleife durchgehen und darin bearbeiten.

gruss kh

Popov 18. Apr 2015 20:30

AW: .csv Datei einlesen, analysieren und bearbeitet abspeichern.
 
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;

Dade 18. Apr 2015 21:54

AW: .csv Datei einlesen, analysieren und bearbeitet abspeichern.
 
Hi Popov,
vielen Dank für den Quellcode.

Da ich totaler Anfänger bin, habe ich folgendes versucht. Ich erstellte ein neues Projekt: (VCL Forms Application)

Darin habe ich einen tbutton eingefügt und per doppelklick geöffnet. Dann direkt da deinen Quellcode eingefügt. Bekomme viele Fehler.

Was mache ich falsch?

himitsu 18. Apr 2015 21:59

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

Zitat von Dade (Beitrag 1298365)
Was mache ich falsch?

Du hast vergessen zu sagen was das für Fehler sind. :roll:

Und natürlich auch nicht erwähnt, welche Delphiversion du verwendest.

Popov 18. Apr 2015 22:23

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

Zitat von Dade (Beitrag 1298365)
Darin habe ich einen tbutton eingefügt und per doppelklick geöffnet. Dann direkt da deinen Quellcode eingefügt. Bekomme viele Fehler

Wie ich schon oben geschrieben habe sind die Fehlermeldungen in der Entwicklungsumgebung normal. Startest das Programm über die EXE siehst du die Fehlermeldungen nicht.

Ich weiß nicht wieso TStringlist mit deinen CSV Dateien nicht klar kommt. Hab mir die Dateien im Hex-Editor angeguckt und da steht am Ende jeder Zeile #13#13#10. Da sollte nur #13#10 stehen. TStringList macht aus dem einzelnen #13 eine leere Zeile, hat aber Probleme sie zu löschen, warum auch immer. Irgendwie bring das den Count von TStringList durcheinander. Deshalb die Fehlermeldungen. Die kann man ignorieren.

Vielleicht kann hier einer Sagen wie man die Fehlermeldungen in der Entwicklungsumgebung abschalten kann. Da ich es schon lange nicht gemacht habe, habe ich es vergessen.

Wie auch immer, kompilieren und dann als Exe ausführen.

Dade 18. Apr 2015 22:26

AW: .csv Datei einlesen, analysieren und bearbeitet abspeichern.
 
Oh,
ja, also ich nutze: Delphi XE7 und bekam diese Fehler:


[dcc32 Error] Unit1.pas(28): E2029 Statement expected but 'USES' found
[dcc32 Error] Unit1.pas(29): E2003 Undeclared identifier: 'FileCtrl'
[dcc32 Error] Unit1.pas(31): E2070 Unknown directive: 'GetFiles'
[dcc32 Warning] Unit1.pas(33): W1002 Symbol 'faArchive' is specific to a platform
[dcc32 Warning] Unit1.pas(33): W1002 Symbol 'faHidden' is specific to a platform
[dcc32 Warning] Unit1.pas(33): W1002 Symbol 'faSysFile' is specific to a platform
[dcc32 Error] Unit1.pas(37): E2003 Undeclared identifier: 'Path'
[dcc32 Error] Unit1.pas(37): E2250 There is no overloaded version of 'IncludeTrailingBackslash' that can be called with these arguments
[dcc32 Warning] Unit1.pas(37): W1002 Symbol 'IncludeTrailingBackslash' is specific to a platform
[dcc32 Error] Unit1.pas(39): E2003 Undeclared identifier: 'ExtMask'
[dcc32 Error] Unit1.pas(39): E2008 Incompatible types
[dcc32 Error] Unit1.pas(41): E2010 Incompatible types: 'string' and 'Integer'
[dcc32 Error] Unit1.pas(43): E2250 There is no overloaded version of 'SameText' that can be called with these arguments
[dcc32 Error] Unit1.pas(44): E2003 Undeclared identifier: 'List'
[dcc32 Error] Unit1.pas(46): E2003 Undeclared identifier: 'SysUtils'
[dcc32 Error] Unit1.pas(49): E2070 Unknown directive: 'TForm1'
[dcc32 Error] Unit1.pas(60): E2003 Undeclared identifier: 'SelectDirectory'
[dcc32 Error] Unit1.pas(60): E2003 Undeclared identifier: 'sdAllowCreate'
[dcc32 Error] Unit1.pas(60): E2003 Undeclared identifier: 'sdPerformCreate'
[dcc32 Error] Unit1.pas(60): E2003 Undeclared identifier: 'sdPrompt'
[dcc32 Error] Unit1.pas(68): E2003 Undeclared identifier: 'GetFiles'
[dcc32 Error] Unit1.pas(80): E2003 Undeclared identifier: 'SaveDialog1'
[dcc32 Error] Unit1.pas(83): E2003 Undeclared identifier: 'Execute'
[dcc32 Error] Unit1.pas(88): E2003 Undeclared identifier: 'FileName'
[dcc32 Error] Unit1.pas(88): E2250 There is no overloaded version of 'ChangeFileExt' that can be called with these arguments
[dcc32 Fatal Error] Project1.dpr(5): F2063 Could not compile used unit 'Unit1.pas'


Damit bekomme ich bestimmt keine .exe.


So habe ich deinen Code eingesetzt in das Fenster, das kommt, wenn ich einen tbutton einfüge und diesen doppelt anklicke:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
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;
end;

Popov 18. Apr 2015 22:32

AW: .csv Datei einlesen, analysieren und bearbeitet abspeichern.
 
Dade, du bist fast ein Doktor. Sowas verpflichtet. Drück bitte noch mal auf BEARBEITEN und setz den Delphi Code in Delphi-Tags:
Code:
[DELPHI]Hier dein Code[/DELPHI]

Dade 18. Apr 2015 23:46

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

Danke für den Hinweis

DeddyH 19. Apr 2015 00:05

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

Delphi-Quellcode:
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin

Da ist wohl beim Kopieren etwas durcheinander geraten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:15 Uhr.
Seite 1 von 7  1 23     Letzte »    

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