Autor |
Beitrag |
Hänsel
Beiträge: 144
|
Verfasst: So 10.11.19 13:23
Hallo,
ich möchte verschiedene .csv-Dateien in eine Datenbank(MSQL)einlesen. Das Problem liegt darin, die einzelnen Datensätze innerhalb einer csv-Datei sind unterschiedlich lang. Ich würde bei jeder einzelnen Zeile die Satzlänge (wieviel Felder hat diese Zeile)abfragen.
Meine Frage: wie kann man diese bei einer csv-Datei realisieren.
Danke im Voraus
Hänsel
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 10.11.19 14:02
Falls du eine aktuelle Enterprise / Architect Edition von Delphi benutzt, kannst du zum Zugriff einfach die Enterprise Connectors verwenden, die sind da seit kurzem dabei, auch für den Zugriff auf .csv Dateien. Dann bekommst du daraus einfach ein Dataset:
www.embarcadero.com/...nterprise-connectors
Die Daten könntest du dann direkt mit Local-SQL aus dem CSV-Dataset in das Zieldataset schieben.
Ansonsten kannst du die Datei zeilenweise durchgehen und die einzelnen Felder manuell auslesen. Wenn dort keine Semikola außer den Trennzeichen enthalten sind, geht das einfach mit einer TStringList und Delimiter/DelimitedText, mit ExtractStrings aus System.Classes oder mit SplitString aus System.StrUtils oder mit dem Stringhelper 'DeinStringWert'.Split() seit XE3.
Der Stringhelper kann auch mit Anführungszeichen usw. umgehen und ist daher ab XE3 die beste Option.
Und dann gibt es natürlich noch diverse CSV-Zugriffsbibliotheken, die du nehmen könntest.
|
|
Hänsel
Beiträge: 144
|
Verfasst: So 10.11.19 16:55
Danke für die Hinweise.
Ich werde alles Zeile für Zeile abfragen müssen. Da diese unterschiedlich lang sind, hätte da jemand für mich einen Ansatz dafür? Die Felder sind mit einem Semikolon getrennt.In der ersten Zeile stehen die Feldnamen (alles o.k.)Mir geht es um die Abfrage am Zeilenende.
Danke im Voraus
Hänsel
|
|
Narses
Beiträge: 10182
Erhaltene Danke: 1255
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 10.11.19 19:18
Moin!
Lies die Datei in eine TStringList ein, dann hast du die Zeilen getrennt. Jetzt nimmst du jede Zeile (=ein Element aus der TStringList) und zählst die Anzahl der Semikola darin -> +1 = Anzahl der Datenfelder.
Ehrlich gesagt, was soll das für eine komische Datei sein, wenn in der ersten Zeile die Spaltenbeschriftungen stehen, dann machen unterschliedlich lange Datensätze danach irgendwie keinen Sinn... ?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: So 10.11.19 23:52
Hallo, wie meinst du das mit unterschiedlich lang? Die Zeilen haben eine unterschiedliche Anzahl von Feldern? Oder die Zeilenlängen sind einfach unterschiedlich?
Das CSV Format definiert ein einheitliches Vorgehen beim kodieren von Text in dem Leerzeichen oder Trenner enthalten sind wobei mit dem trenner einzelenen Felder unterschieden werden.
Du brauchst zum einlesen einer solchen Datei zwei Stringlisten. Die erste, ich nenne sie mal SL, lädt die komplette Datei via LoadFromFile.
Die zweite Stringliste, hier mal mit Line bezeichnet, wird erst configuriert, so dass der Feldtrenner in CommaText eingetragen ist. Normalerweise braucht man das nicht ändern wenn man CSV einliest.
über n = 0..SL.Count-1
Line.CommaText := SL.Strings[n]
über x = 0.. Line.Count-1
Line.Strings[x] liefert die Feldnamen oder Feldinhalte falls die erste Zeile keine Namen enthält.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 11.11.19 07:14
Hänsel hat folgendes geschrieben : | Ich werde alles Zeile für Zeile abfragen müssen. Da diese unterschiedlich lang sind, hätte da jemand für mich einen Ansatz dafür? |
Zeig doch einfach mal wie weit du kommst. Dann können wir sicher auch besser helfen. Denn einige Möglichkeiten hatte ich ja verlinkt und Narses und Sinspin haben ja jetzt auch noch Hinweise gegeben.
Im Moment ist mir nicht klar womit du eigentlich Probleme hast. Das Splitten pro Zeile scheint ja zu klappen, wenn ich das richtig interpretiert habe:
Hänsel hat folgendes geschrieben : | In der ersten Zeile stehen die Feldnamen (alles o.k.) |
Die Hänsel hat folgendes geschrieben : | Abfrage am Zeilenende |
hängt davon ab was du dann mit den Daten machen möchtest. Denn erst einmal kannst du mit einer Schleife ja alle Elemente durchgehen, egal wie viele es in einer Zeile sind. Die Schleifenenden hat Sinspin ja mittlerweile auch genannt.
|
|
doublecross
Beiträge: 149
Erhaltene Danke: 27
Windows 7
C#; Visual Studio 2015
|
Verfasst: Mo 11.11.19 10:19
Hi,
Narses hat folgendes geschrieben : | Ehrlich gesagt, was soll das für eine komische Datei sein, wenn in der ersten Zeile die Spaltenbeschriftungen stehen, dann machen unterschiedlich lange Datensätze danach irgendwie keinen Sinn... ? |
da sind mir in meiner Karriere schon etliche CSV "ähnlice" Dateien untergekommen in den es solche Situationen gab.
Beliebt sind so Dinge wie: Das erste Feld der Zeile bestimmt welche Felder wirklich gefüllt werden
oder: Wenn eine Leerzeile auftaucht ist die Zeile danach ein neuer "Tabellenanfang", sie enthält also die Feldnamen der nächsten Datenstruktur.
Da gibt es die "interessantesten" Konstrukte. in freier Wildbahn.
Narses hat folgendes geschrieben : | Lies die Datei in eine TStringList ein, dann hast du die Zeilen getrennt. Jetzt nimmst du jede Zeile (=ein Element aus der TStringList) und zählst die Anzahl der Semikola darin -> +1 = Anzahl der Datenfelder. |
In dem Fall muss man aber aufpassen, wenn es gequotete Texte gibt, dann muss man die Semikola welche in quotes stehen wieder gesondert behandeln und gegebenenfalls die Quote Symbole entfernen. Alles kein Hexenwerk, man sollte sich der Sonderfälle aber bewusst sein, ehe man loslegt.
doublecross
|
|
Hänsel
Beiträge: 144
|
Verfasst: Mo 11.11.19 11:57
Hallo ,
anbei habe ich mal einen Ausschnitt aus einer csv-Datei beigelegt.
Quelltext 1: 2: 3: 4: 5: 6:
| Zeile 2 RAW4DATE 01-01-0001 //Zeile 2/3/4 enden hier Zeile 3 RAW4DATE 01-01-0001 Zeile 4 RAW4DATE 01-01-0001 Zeile 5 27 Einheiten (H.C.A.) 15.01.2018 52 Zeile 5/6/7 enden hier Zeile 6 60 Einheiten (H.C.A.) 15.01.2018 110 Zeile 7 0,007 m³ Volumen 31.05.2018 0,006 |
Weiter Zeilen können aber auch noch andere Satzlängen haben.
Gibt es nicht die Möglichkeit vor Beginn z.B. der Zeile 2 die Anzahl der Felder zu Zählen. Wenn ja wie?
Noch soviel dazu, von hieraus (csv) werden die Daten in eine SQL Tabelle geschrieben. Die Fehlermeldung erscheint dann, wenn ich z.B. bei Zeile 2 am Satzende bin und weiter das nächste Feld (was es ja nicht gibt) abfrage.
MFG
Hänsel
Moderiert von Th69: Code-Tags hinzugefügt
|
|
doublecross
Beiträge: 149
Erhaltene Danke: 27
Windows 7
C#; Visual Studio 2015
|
Verfasst: Di 12.11.19 10:00
Hi,
Hänsel hat folgendes geschrieben : | anbei habe ich mal einen Ausschnitt aus einer csv-Datei beigelegt. |
was ist denn da als Trennzeichen Verwendet? Ein Tab? Oder haben die Felder eine Feste Bereite? Woher weißt du, wie du den Wert aus Spalte X zu interpretieren kannst?
|
|
Hänsel
Beiträge: 144
|
Verfasst: Di 12.11.19 22:35
Hi
Danke für alle Hinweise.
Meine Frage ist indessen beantwortet.
Nochmals Danke
|
|
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: So 17.11.19 22:34
Hallo, wäre schön zu wissen wo und wie deine Frage beantwortet wurde, so dass wir alle was davon haben.
Danke auch.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|