Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi XLS in CSV (https://www.delphipraxis.net/173366-xls-csv.html)

Maya 20. Feb 2013 08:59

XLS in CSV
 
Hallo ihr Lieben,

in meinen Programm lasse ich bisher CSV-Dateien einlesen, die dann auf eine Datenbank kommen und dort geprüft werden. Ist ja alles schön und gut. Manche Dateien, die eingelesen werden müssen, sind aber XLS-Dateien, die "so einfach" nicht eingelesen werden können. Mein Wunschtraum wäre es nun, dass bei der Auswahl der Datei sie intern(?) in eine CSV/TXT umgewandelt wird. Die Datei braucht nicht lange zu existieren, da ich in einer Stringlist den Inhalt abspeichere und mir daraus dann die notwendigen Infos nach und nach 'rausziehe.
Damit ihr mal eine Vorstellung bekommt:

Delphi-Quellcode:
procedure ReadFile();
var i:Integer;
    aBuffer:String;
begin
  if Datenliste<>Nil then FreeAndNil(Datenliste);
  Datenliste:=TStringList.Create;
  Datenliste.LoadFromFile(Dateiname);

  for i:=0 to Datenliste.Count-1 do
    begin
      aBuffer:=Datenliste.Strings[i];
      if (aBuffer[Length(aBuffer)]<>';')
      then aBuffer:=aBuffer+';';

      aBuffer:=StringReplace(aBuffer, '"', '', [rfReplaceAll]);
      Datenliste.Strings[i]:=aBuffer;
    end;
end;
Im Netz bin ich bisher nicht wirklich schlau geworden, da ging es immer eher darum, dass man aus Delphi etwas in Excel-Dateien speichern wollte.
Habt ihr einen ultimativen Tipp für mich? :)

Union 20. Feb 2013 10:47

AW: XLS in CSV
 
Hier mal ein Beispiel wie Du (in Verbindung mit ADO) den Import aus CSV und XLS hinbekommst. Nach der Anweisung ADOQueryImport.Open hast Du dann die Daten als ADO-Datenmenge vorliegen und kanns beliebig weiterspielen:
Delphi-Quellcode:
procedure TfrmPosImport.btnReadDataClick(Sender: TObject);
var
   TableNames : TStringList;
   PropString, DataSource : string;
begin
   ADOConnectionImport.Connected := False;
   TableNames := TStringList.Create;

   if ExtractFileExt(edtFileName.Text) = '.xls' then
   begin
      PropString := '"Excel 8.0;HDR=Yes"';
      DataSource := edtFileName.Text;
   end
   else
   begin
      PropString := '"text;HDR=Yes;FMT=Delimited"';
      DataSource := ExtractFilePath(edtFileName.Text);
      TableNames.Add(ExtractFileName(edtFileName.Text));
   end;

   ADOConnectionImport.ConnectionString :=
      'Provider=Microsoft.Jet.OLEDB.4.0;'+
      'Data Source='+DataSource+';'+
      'Mode=Read;'+
      'Extended Properties='+PropString+';'+
      'Persist Security Info=False';

   if TableNames.Count = 0 then
      ADOConnectionImport.GetTableNames(TableNames);

   if TableNames.Count > 0 then
   begin
      ADOQueryImport.Active := False;
      cxgImportDBTableViewImport.ClearItems;
      ADOQueryImport.SQL.Clear;
      ADOQueryImport.SQL.Add('Select * from ['+TableNames[0]+'] where id is not null');
      ADOQueryImport.Open;
      // Hier erfolgt die Anzeige in einem Grid, aber man kann mit dem ADOQueryImport machen was man will
      cxgImportDBTableViewImport.DataController.CreateAllItems;
      cxgImportDBTableViewImport.ApplyBestFit();
   end;
   TableNames.Free;
end;

Maya 20. Feb 2013 13:06

AW: XLS in CSV
 
Ich habe mir das mal so umgestrickt, wie ich es mir wünsche, aber leider funktioniert das noch nicht.

Delphi-Quellcode:
procedure XLStoCSV;
var S: String;
    XLSStringlist: TStringlist;
    i, j: Integer;
begin
  XLSStringlist:=TStringlist.Create;
  try
    with PatBehandlungData.conADO do
      begin
        Connected:=False;
        ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+
                          Dateiname +'; Mode=Read;'                     +
                          'Extended Properties="Excel 8.0;HDR=Yes";'    +
                          'Persist Security Info=False';
        Connected:=True;
      end;

    with PatBehandlungData.qryAdo do
      begin
        Active:=False;
        SQL.Clear;
        SQL.Add('SELECT * FROM ['+ExtractFileName(Dateiname)+'] WHERE ID IS NOT NULL');
        Active:=True;
        Open;        //HIER knallt es
      end;

    for i := 0 to PatBehandlungData.qryAdo.RecordCount-1 do
      begin
        S:='';
        for j := 0 to PatBehandlungData.qryAdo.FieldCount - 1 do
          begin
            if S<>'' then S:=S+';';
            S:=S+PatBehandlungData.qryAdo.Fields[j].AsString;
          end;
        XLSStringlist.Add(S);
      end;
  finally
    Dateiname:=ExtractFilePath(Dateiname)+ChangeFileExt(ExtractFileName(Dateiname),'csv');
    XLSStringlist.SaveToFile(Dateiname);
    XLSStringlist.Free;
  end;
Als Fehlermeldung kommt:
Code:
Erste Gelegenheit für Exception bei $7C812FD3. Exception-Klasse EOleException mit Meldung 'Das Microsoft Jet-Datenbankmodul konnte das Objekt 'Rheuma 4.Quartal 2011_versandt.xls' nicht finden. Stellen Sie sicher, dass das Objekt existiert und dass die Namens- und Pfadangaben richtig eingegeben wurden'. Prozess ExportExcel.exe (1140)
Die Datei existiert auf jeden Fall, weil ich einmal den Dateinamen aus dem JvFilenameEdit auslese und das dann die Variable "Dateiname" ergibt. Es dürfte ja dann auch vorher keine Connection entstehen, oder?

p80286 20. Feb 2013 14:15

AW: XLS in CSV
 
Hast Du es denn mal mit "Rheuma 4.Quartal 2011_versandt.xls" versucht?

Gruß
K-H

Union 20. Feb 2013 14:38

AW: XLS in CSV
 
Du hast vergessen das Arbeitsmappen-Objekt anzugeben. Der Dateiname wird durch den Connection-String als DataSource gesetzt. Der Arbeitsmappen-Name (immer die erste) wird als Tabellenname im SQL angegeben.
Delphi-Quellcode:
TableNames := TStringList.Create;

with PatBehandlungData.qryAdo do
begin
  Active:=False;
  // Einlesen der Arbeitsmappen-Namen
  GetTableNames(TableNames);
  SQL.Clear;
  // Übergabe der ersten Arbeitsmappe als Tabellenname,
  // das WHERE ist mal auskommentiert
  SQL.Add('SELECT * FROM ['+TableNames[0]+'] --WHERE ID IS NOT NULL');
  Active:=True;
  Open; //HIER knallt es
end;

TableNames.Free;

Maya 20. Feb 2013 18:49

AW: XLS in CSV
 
Zitat:

Zitat von p80286 (Beitrag 1204479)
Hast Du es denn mal mit "Rheuma 4.Quartal 2011_versandt.xls" versucht?

Gruß
K-H

Wie schon gesagt, die Datei existiert auf jeden Fall, weil ich einmal den Dateinamen aus dem JvFilenameEdit auslese und das dann die Variable "Dateiname" ergibt. Die Variable wird ansonsten zu keinen Zeitpunkt verändert.

Zitat:

Zitat von Union (Beitrag 1204481)
Du hast vergessen das Arbeitsmappen-Objekt anzugeben. Der Dateiname wird durch den Connection-String als DataSource gesetzt. Der Arbeitsmappen-Name (immer die erste) wird als Tabellenname im SQL angegeben.

Ich probiere das morgen früh gleich auf Arbeit aus. Danke für die Hilfe!

Maya 21. Feb 2013 06:15

AW: XLS in CSV
 
So, sry für Doppelpost.

Ich habe das entsprechend noch geändert. Mein Quellcode sieht nun wie folgt aus.

Delphi-Quellcode:
procedure XLStoCSV;
var S: String;
    Tabellennamen, XLSStringlist: TStringlist;
    i, j: Integer;
begin
  XLSStringlist:=TStringlist.Create;
  Tabellennamen:=TStringList.Create;
  try
    with PatBehandlungData.conADO do
      begin
        Connected:=False;
        ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+
                          Dateiname +'; Mode=Read;'                     +
                          'Extended Properties="Excel 8.0;HDR=Yes";'    +
                          'Persist Security Info=False';
        Connected:=True;
        GetTableNames(Tabellennamen);
      end;

    with PatBehandlungData.qryAdo do
      begin
        Active:=False;
        SQL.Clear;
        SQL.Add('SELECT * FROM ['+Tabellennamen.Strings[0]+']');
        Active:=True;
        Open;
      end;

    for i := 0 to PatBehandlungData.qryAdo.RecordCount-1 do
      begin
        S:='';
        for j := 0 to PatBehandlungData.qryAdo.FieldCount - 1 do
          begin
            if S<>'' then S:=S+';';
            S:=S+PatBehandlungData.qryAdo.Fields[j].AsString;
          end;
        XLSStringlist.Add(S);
      end;
  finally
    Dateiname:=ExtractFilePath(Dateiname)+ChangeFileExt(ExtractFileName(Dateiname),'.csv');
    XLSStringlist.SaveToFile(Dateiname);
    XLSStringlist.Free;
  end;
end;
Die WHERE-Klausel musste ich herausnehmen, weil immer wieder dort Exceptions kamen, egal ob auskommentiert mit -- oder nicht. Ich muss mal noch schauen, in wieweit sich das auswirkt, aber danke noch mal für die Hilfe. :)

jobo 21. Feb 2013 07:55

AW: XLS in CSV
 
Die Where Clause musste ich rausnehmen
Ich würde beim Import generell eine Zwischentabelle in meine Standard DB wählen, hier alles ungeprüft "reinkippen" (Reinkippen bedeutet notfalls, alle Feldtypen auf TEXT und "groß genug").
Erst dann auf diesen Daten eine Analyse/Feldtyp-Konvertierung/Filterung vornehmen. Man kann so viel gezielter reagieren und kontrollieren.

Maya 21. Feb 2013 09:05

AW: XLS in CSV
 
Ich habe jetzt noch das Problem mit den Spaltennamen (also die Überschriften) geklärt. Ich habe noch folgendes eingefügt:

Delphi-Quellcode:
   
PatBehandlungData.qryAdo.GetFieldNames(Feldernamen);
    S:='';
    for i := 0 to Feldernamen.Count - 1 do
      begin
        if S<>'' then S:=S+';';
        S:=S+Feldernamen.Strings[i];
      end;
    XLSStringlist.Add(S);
Somit hat man dann eine recht genaue Kopie von der XLS mit den Überschriften, die ich für meine Zwecke dringend benötige.

Sir Rufo 21. Feb 2013 12:28

AW: XLS in CSV
 
Warum setzt du
Delphi-Quellcode:
Active := true;
und dann nochmal ein
Delphi-Quellcode:
Open;
?
Das ist doch doppelt gemoppelt ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:07 Uhr.
Seite 1 von 2  1 2      

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