![]() |
CSV Dateien über OLE importieren, falsches Format in Feldern
Hallo,
ich arbeite an einem Programm, welches Datensätze aus extra dafür erstellten Excelvorlagen über OLE ausliest und in ein entsprechendes Übertragungsformat umwandelt (Übertragungsdatei ist reines Textformat). Nun kam von Kundenseite der Wunsch hinzu auch CSV Dateien einlesen und übertragen zu können. An sich kein Problem, solange sich die erstellte CSV Datei an der Excelvorlage orientiert. Sprich es sollen bei der Umwandlung die gleichen Codierungs-Funktionen bei der CSV-Datei zum Einsatz kommen, wie auch schon bei den bisherigen Excel-Dateien, um sich größere Arbeiten an der eigentlichen Programmlogik selbst zu ersparen. Nun tritt das Problem auf, dass die Daten der CSV-Datei von Excel falsch interpretiert werden und die einzelnen Felder mit diversen leider unpassenden Formaten belegt werden und diese falsch dargestellten Daten vom Programm anschließend auch so übernommen werden. Als Beispiel aus dem Uhrzeit-String "12:20" wird "0,513888888888889" ausgelesen oder aus "01.06.2007" wird "39234" usw. Das merkwürdige ist auch, öffne ich die CSV-Datei mit Excel, werden die meisten Daten noch korrekt dargestellt. Wandle ich jetzt aber das Arbeitsblatt in das eigentlich benötigte Text-Format um, so ist ein Großteil der Datensätze unbrauchbar geworden. Deshalb funktioniert es leider auch nicht, das Arbeitsblatt zu Beginn als Text-Format zu formatieren.
Delphi-Quellcode:
Andere Versuche waren es einzelne Felder mit .NumberFormat zu formatieren, was auch nicht zum Erfolg führte.
ExcelApp:=CreateOLEObject('Excel.Application');
ExcelApp.Visible:=false; ExcelApp.DisplayAlerts:=False; ExcelApp.Workbooks.Open(Excelvorlage.text); ExcelApp.Workbooks[1].Worksheets[1].Select; ExcelApp.Selection.NumberFormat := '@'; Z.B. in der CSV-Datei steht "06:00". Excel interpretiert dies als benutzerdefiniertes Format und macht daraus "06:00:00" (auch wenn weiterhin "06:00" angezeigt werden). Delphi liest aus diesem Benutzerdefinierten-Feld nun aber "0,25" aus. Ändert man nun das Zellenformat in Text macht Excel von sich aus daraus ebenfalls wieder eine falsche "0,25", die so natürlich auch ausgelesen wird. Das voranstellen eines Hochkommas brachte ebenso nichts, da hierbei auch nicht die richtigen Ursprungsdaten ausgelesen werde, sondern die falsch dargestellten einschließlich dem hinzugefügten Hochkomma. Und mein dritter nicht brauchbarer Lösungsansatz war es, die CSV-Datei einfach temporär ins Excel-Format zu speichern und dann wieder einzulesen. Dies klappte allerdings auch nicht, da diese Datei von Excel nicht mehr erkannt wird. Ich häng an diesem Problem/Denkfehler schon den ganzen Vormittag fest und habe noch keine brauchbare Lösung gefunden. Aber es sollte doch irgendwie möglich sein, Daten aus CSV-Files mit dem Umweg über Excel in ein Delphi-Programm zu importieren? Danke und Gruß Arne |
Re: CSV Dateien über OLE importieren, falsches Format in Fel
Wenn ich das richtig verstehe, soll zusätzlich zu der Variante Excel->Text eine neue Variante CSV->Text entstehen. Warum dann der Umweg über Excel? Mache doch die Umwandlung selbst.
|
Re: CSV Dateien über OLE importieren, falsches Format in Fel
@ iKilledKenny
Ja du hast das schon richtig verstanden und wäre ja auch normal die beste Lösung. Nur ist bei uns der Programmteil, welcher die unzähligen Nachrichtenvorlagen auswertet und in eines von n Übertragungsformaten umwandelt schon über 50k Zeilen Source groß und bisher nur zur Verarbeitung von Excel-Dateien vorbereitet. Darum wären hier Änderungen viel zu aufwendig und der Umweg über Excel notwendig. Es scheitert ja im Prinzip auch nur daran, dass Excel die Felder mit unpassenden Formaten belegt, weshalb die Daten falsch ausgelesen werden. Dies muss doch irgendwie zu unterbinden sein? |
Re: CSV Dateien über OLE importieren, falsches Format in Fel
siehe
![]() Ziemlich unten ("Um eine Zelle im generellen Zahlenformat zu formatieren:"), ich denke das ists, was du suchst. |
Re: CSV Dateien über OLE importieren, falsches Format in Fel
Hi ArneWolf,
ich verstehe dein Problem nicht. CSV ist doch auch nur eine Textdatei. Du wandelst Text in Text. Da ist doch nichts dran. Was kann dir passieren? Doch nur variable <-> feste Länge der Felder; Strings in Hochkommata. Das machst du doch auf dem direkten Weg nebenbei beim Frühstück. Deinen Aufwand über Exel versteh ich da nicht. Auch wenn die Unit 50k Code enthält macht die kleine Funktion den Kohl doch nicht fett. gruß oki |
Re: CSV Dateien über OLE importieren, falsches Format in Fel
Hallo,
vielen Dank für die rege Beteiligung und die guten Lösungsansätze. Habe es jetzt mit einer Hilfsfunktion gelöst, die mir die CSV-Datei auf einer temporären als Text formatierten Excel-Arbeitsmappe einliest und zwischenspeichert. Hat den Vorteil, dass man dieser leeren Arbeitsmappe bei Bedarf alle möglichen Formatierungen mitgeben kann. Ich stelle die Funktion auch mal hier zur Verfügung, falls jemand ein ähnliches Problem mit dem einlesen von CSV nach Excel und den daraus folgenden falschen Feld-Formatierungen haben sollte. Hat allerdings bisher noch 3 Einschränkungen, da diese bei unserem Einsatzzweck alle nicht auftreten können. Sollte aber kein Ding sein dies bei Bedarf noch zu erweitern. - Separator-Zeichen innerhalb von Nutzdaten werden nicht abgefangen - keine Berücksichtigung von Datenklammerzeichen - CSV-Dateien, die nur aus einer einzigen Spalte bestehen, werden falsch eingelesen
Delphi-Quellcode:
function CsvToExcel(Eingabe:string):boolean;
var CsvArray:TStringDynArray; ArrayMax, SegmentNr, Zeile, Spalte, PosUmbruch, Zeilenumbruchnacher:integer; CsvExcel:variant; begin Eingabe := StringReplace(Eingabe,#$D#$A,'<><><>',[rfReplaceAll]); //Zeilenumbruch abfangen, da hiermit innerhalb des Arrays nicht mehr gearbeitet werden kann CsvArray := explode(';', Eingabe); //explode und StringReplace bei großen Dateien besser durch etwas schnelleres ersetzen! SegmentNr := 0; Zeile := 1; Spalte := 1; CsvExcel := CreateOLEObject('Excel.Application'); try CsvExcel.Visible:=false; CsvExcel.DisplayAlerts:=false; CsvExcel.Workbooks.Open(ExtractFilePath(ParamStr(0))+'resources\csv.xls'); CsvExcel.Workbooks[1].Worksheets[1].Select; repeat if (CsvArray[0+SegmentNr] <> '') and (copy(CsvArray[0+SegmentNr],1,6) <> '<><><>') then begin if (POS('<><><>',CsvArray[0+SegmentNr]) > 0) then begin PosUmbruch := PosEx('<><><>', CsvArray[0+SegmentNR]); CsvExcel.cells[Zeile,Spalte] := copy(CsvArray[0+SegmentNR], 1, PosUmbruch-1); Spalte := 1; Zeile := Zeile+1; CsvExcel.cells[Zeile,Spalte] := copy(CsvArray[0+SegmentNR], PosUmbruch+6); SegmentNr := SegmentNr+1; Spalte := Spalte+1; continue; end else begin CsvExcel.cells[Zeile,Spalte] := CsvArray[0+SegmentNR]; SegmentNr := SegmentNr+1; Spalte := Spalte+1; continue; end; end else if (copy(CsvArray[0+SegmentNr],1,6) = '<><><>') then begin Spalte := 1; Zeile := Zeile+1; CsvExcel.cells[Zeile,Spalte] := copy(CsvArray[0+SegmentNR],7); SegmentNr := SegmentNr+1; Spalte := Spalte+1; continue; end else begin SegmentNr := SegmentNr+1; Spalte := Spalte+1; continue; end; until (SegmentNr = length(CsvArray)-1); except begin CsvExcel.quit; CsvExcel := unassigned; Result := false; exit; end; end; CsvExcel.ActiveWorkBook.SaveAs(ExtractFilePath(ParamStr(0))+'resources\'+'tmp.xls'); CsvExcel.quit; CsvExcel := unassigned; Result := true; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:27 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