![]() |
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:
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.
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; Habt ihr einen ultimativen Tipp für mich? :) |
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; |
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:
Als Fehlermeldung kommt:
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;
Code:
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?
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)
|
AW: XLS in CSV
Hast Du es denn mal mit "Rheuma 4.Quartal 2011_versandt.xls" versucht?
Gruß K-H |
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; |
AW: XLS in CSV
Zitat:
Zitat:
|
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:
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. :)
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; |
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. |
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:
Somit hat man dann eine recht genaue Kopie von der XLS mit den Überschriften, die ich für meine Zwecke dringend benötige.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); |
AW: XLS in CSV
Warum setzt du
Delphi-Quellcode:
und dann nochmal ein
Active := true;
Delphi-Quellcode:
?
Open;
Das ist doch doppelt gemoppelt ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz