Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi CSV Textdatei in Memtable laden und mit Query abfragen (https://www.delphipraxis.net/211669-csv-textdatei-memtable-laden-und-mit-query-abfragen.html)

fisipjm 20. Okt 2022 13:56

Datenbank: SQLite • Version: 1.0 • Zugriff über: Firedac

CSV Textdatei in Memtable laden und mit Query abfragen
 
Hi,

Ich steh mal wieder auf Kriegsfuß mit den Batchmove komponenten oder der Memtable, da bin ich mir tatsächlich nicht ganz sicher :?

Ich möchte folgendes Erreichen:
Ich habe CSV Dateien (Der Aufbau und die Zusammensetzung sind hier egal, das einzige was zählt, sie sind Syntaktisch korrekt) die CSV Dateien möchte ich am Schluss in der Form im Programm haben, dass ich Sie mit Standard SQL abfragen kann. Es soll keine Zusätzliche Connection zu einem externen DBMS nötig sein, also habe ich folgedes versucht, das eigentlich auch soweit schon funktioniert.

BatchmoveTextReader --> Liest CSV
BatchmoveDatasetWriter --> Schreibt in Memtabale
FDconnection, LocalSQL und SQLitePhysLink --> Kümmern sich brav darum die Memtable im Speicher zur Verfügung zu stellen
FDQuery --> Quatscht brav mit der Memtable über die LocalSQL Anbindung
Batchmove --> Kümmer sich um dasd "Felder Raten" und die Anlage der korrepondierenden Felder in der Memtable

Mein Problem ist folgendes, beim ersten mal ausführen von FDBatchmove.GuessFormat und FDBtchmove.Execute werden automatisch in der Memtable die Fielddefs erstellt. Leider bekomme ich diesen Prozess im Code nicht wiederholt, so dass ich als nächstes eine andere Datei einlesen kann. Ich bekomme dann die unterschiedlichsten Fehlermeldungen. Entweder, dass die Quell und Zielfelder nicht passen, das die Datenmenge nicht offen ist, dass die Datenmenge nicht initialisiert ist... ich dreh mich irgendwie im Kreis.

Die Frage ist also, wie bekomme ich die Batchmove komponenten dazu überredet, bei einem 2. durchlauf, die Felder in meiner Memtable wieder neu zu erstellen?

Uwe Raabe 20. Okt 2022 14:12

AW: CSV Textdatei in Memtable laden und mit Query abfragen
 
Hast du poClearDest oder poClearDestNoUndo in den BatchMove Options aktiv?

Eventuell musst du die Zieltabelle auch vorher löschen.

fisipjm 24. Okt 2022 10:23

AW: CSV Textdatei in Memtable laden und mit Query abfragen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Uwe,

danke für den Hinweis, dass hat zum Teil schon geholfen. Kannst du mir einen kleinen Gefallen tun :oops:
Ich habe in den Anhang eine Zip gepackt mit einem kleinen Programm das mein derzeitiges Problem verdeutlicht. In der Zip sind auch 2 CSV Dateien mit drin. Ich verstehen nicht waum der Import nicht funktioniert. Die GuessFormat Funktion gibt einfach keine Feldbezeichnungen zurück und ich verstehe nicht warum.
Ich befürchte langsam seh ich vor lauter Wald keine Bäume mehr.

grüß
PJM

Uwe Raabe 24. Okt 2022 11:44

AW: CSV Textdatei in Memtable laden und mit Query abfragen
 
Damit GuessFormat die erste Zeile als Feldnamen interpretiert, müssen diese entweder groß geschrieben werden oder es müssen bei den Feldwerten auch nicht-String Werte gefunden werden.

Im Allgemeinen sollte man auf GuessFormat lieber verzichten, da das Ergebnis nicht wirklich stabil ist. Wenn man das Format kennt, trägt man es besser im Reader.DataDef korrekt ein.

fisipjm 24. Okt 2022 15:14

AW: CSV Textdatei in Memtable laden und mit Query abfragen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1513723)
Damit GuessFormat die erste Zeile als Feldnamen interpretiert, müssen diese entweder groß geschrieben werden oder es müssen bei den Feldwerten auch nicht-String Werte gefunden werden.

Im Allgemeinen sollte man auf GuessFormat lieber verzichten, da das Ergebnis nicht wirklich stabil ist. Wenn man das Format kennt, trägt man es besser im Reader.DataDef korrekt ein.

Woher hast du die Informationen für GuessFormat? Ich finde in der Hilfe von Emba leider nur sehr spärliche Informationen. Mein Ziel ist es ja eigentlich auch nur mir ein bisschen Arbeit zu sparen. Ich mache mit GuessFormat die Datadefs in dem Reader voll und dann passe ich alles an, was nicht passt (Datum,Bool, etc.), der Rest, der ordentlich erkannt wird, kann ja weiter über GuessFormat laufen. Oder siehst du das anders.

Uwe Raabe 24. Okt 2022 15:38

AW: CSV Textdatei in Memtable laden und mit Query abfragen
 
Zitat:

Zitat von fisipjm (Beitrag 1513739)
Woher hast du die Informationen für GuessFormat?

Die Sourcen natürlich.
Delphi-Quellcode:
      // When a value is upper-cased, this is a "good" sign, that
      // the value is field name
      if not CheckSet(sItem, ['A'..'Z', '_'], ['A'..'Z', '0'..'9', '_', '#', '$']) then
        lFieldNamesUC := False;

...

    // Final guess about first line
    DataDef.WithFieldNames := lFieldNames and (not lAllStrings or lFieldNamesUC);
Zitat:

Zitat von fisipjm (Beitrag 1513739)
Ich mache mit GuessFormat die Datadefs in dem Reader voll und dann passe ich alles an, was nicht passt (Datum,Bool, etc.), der Rest, der ordentlich erkannt wird, kann ja weiter über GuessFormat laufen. Oder siehst du das anders.

Das kannst du natürlich machen. In dem Fall solltest du den Reader bzw. Writer aber lieber nicht anonym anlegen, da du dann eben nicht so einfach an die entsprechenden Properties kommst.
Delphi-Quellcode:
       with TFDBatchMoveTextReader.Create(lBatchmove) do

...

        with TFDBatchMoveDataSetWriter.Create(lBatchmove) do

fisipjm 24. Okt 2022 15:44

AW: CSV Textdatei in Memtable laden und mit Query abfragen
 
[QUOTE=Uwe Raabe;1513741]
Zitat:

Zitat von fisipjm (Beitrag 1513739)
Woher hast du die Informationen für GuessFormat?

Die Sourcen natürlich.
Delphi-Quellcode:
      // When a value is upper-cased, this is a "good" sign, that
      // the value is field name
      if not CheckSet(sItem, ['A'..'Z', '_'], ['A'..'Z', '0'..'9', '_', '#', '$']) then
        lFieldNamesUC := False;

...

    // Final guess about first line
    DataDef.WithFieldNames := lFieldNames and (not lAllStrings or lFieldNamesUC);
:gruebel: wie kommst du an die Source. Bei mir ist nach dem interface ( IFDBatchMoveReader = interface(IFDBatchMoveDriver) ) Schluss.:pale:
Ich befürchte ich stell mich grad richtig doof dran :oops:

Uwe Raabe 24. Okt 2022 16:13

AW: CSV Textdatei in Memtable laden und mit Query abfragen
 
Zitat:

Zitat von fisipjm (Beitrag 1513743)
:gruebel: wie kommst du an die Source.

Strg-Klick auf
Delphi-Quellcode:
TFDBatchMoveTextReader
->
Delphi-Quellcode:
GuessFormat
.

Übrigens: Du setzt dort nach dem Create zwar die DataDef-Eigenschaften, die werden aber bei GuessFormat wieder überschrieben. Du solltest also das GuessFormat nach dem Setzen von FileName aber vor den Einstellungen von DataDef aufrufen.

fisipjm 25. Okt 2022 08:14

AW: CSV Textdatei in Memtable laden und mit Query abfragen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1513747)
Zitat:

Zitat von fisipjm (Beitrag 1513743)
:gruebel: wie kommst du an die Source.

Strg-Klick auf
Delphi-Quellcode:
TFDBatchMoveTextReader
->
Delphi-Quellcode:
GuessFormat
.

Übrigens: Du setzt dort nach dem Create zwar die DataDef-Eigenschaften, die werden aber bei GuessFormat wieder überschrieben. Du solltest also das GuessFormat nach dem Setzen von FileName aber vor den Einstellungen von DataDef aufrufen.

Danke. Heute Morgen hab ich die Kommentare dann auch gesehen/gefunden. Kaffee sei dank :)
Über die Sinnhaftigkeit der Definition, was eine Überschrift ist, lässt sich sicher streiten, aber das hat mir schon mal sehr weiter geholfen.
Vielen Dank, Top-Hilfestellung wie immer :thumb:

Ps.: Danke für den Hinweis mit den DataDef Eigenschaften. Hatte ich zwischenzeitlich sogar schon geändert und die Eigenschaft sogar um eine kleine Helper Class erweitert, damit ich mir das Geschachtel bei der Prüfung auf Nil spare.

Delphi-Quellcode:
type
  TFDTextFieldHelper = class helper for TFDTextField
  private
    function getter: TFDTextDataType;
    procedure setter(const Value: TFDTextDataType);
  published
    property DataTypeNilSafe: TFDTextDataType read getter write setter;
  end;

....

{ TFDTextFieldHelper }

function TFDTextFieldHelper.getter: TFDTextDataType;
begin
  if Self <> nil then
    result := Self.DataType
end;

procedure TFDTextFieldHelper.setter(const Value: TFDTextDataType);
begin
  if Self <> nil then
    Self.DataType := Value;
end;

...


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:53 Uhr.

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