Entwickler-Ecke

Datenbanken - Query-Ergebnismenge in eine csv-Datei schreiben


gamoes - So 12.03.06 18:01
Titel: Query-Ergebnismenge in eine csv-Datei schreiben
Hallo,
in meinem Programm erstelle ich über ADO-Query eine Ergbnismenge, die ich in eine csv-Datei ablegen will, in der die einzelnen Spalten durch Semikolon getrennt sind.
Bisher hab ich es nur geschafft von meinem Programm aus ein Word-Dokument zu starten.
Die csv-Datei will ich als Datenquelle für Word nutzen, damit ich dann einen Serienbrief erstellen kann. Also Das Worddokument mit der Datenquelle verbinden.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure Tfrm_Bewerber.Eingangsbesttigung1Click(Sender: TObject);
var word: Variant;
begin
  Application.CreateForm(Tfrm_Empfang, frm_Empfang);
   frm_Empfang.Show;
   frm_Bewerber.Hide;
  try
   word:=CreateOleObject('Word.Application')
  except
   ShowMessage('WORD konnte nicht gestartet werden !');
   Exit
  end;
   word.Visible := True;
   word.Documents.Open(FileName:='d:\oraclewin\persinfo_azubi_d\docs\eingang.doc'); 
end;


Gruß
Gabi

Moderiert von user profile iconAXMD: Delphi-Tags hinzugefügt


mkinzler - So 12.03.06 18:19

Hallo Gabi,

wenn die csv-datei erstellt ist, und der Serienbrief mit dieser datei verknüpft ist. sollte der Code eigentlich schon ausreichend sein. Oder was willst du realisireen?


gamoes - So 12.03.06 18:39

Hallo,
ich will die csv-Datei erst noch erstellen und weiß nicht wie.
Die Datensätze, die mir über mein SELECT ausgegeben werden, sollen in eine csv-Datei eingetragen werden.
Bin in Delphi noch nicht so sehr fit.

Gruß
Gabi


mkinzler - So 12.03.06 18:46

Ich würde das einfach durch eine WriteLn-Aufruf erledigen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
...
   s := AdoQuery.Fields.FieldByNumber(0).AsString
   for i := 1 to AdoQuery.FieldCount-1  do begin
      s := s + ';' + AdoQuery.Fields.FieldByNumber(i).AsString;
   end;
   WriteLn ( f, s);
...


gamoes - Mo 13.03.06 18:00

mit Writeln klappt das bei mir noch nicht so ganz.
Hab jetzt eben gesehen, dass man auch mit QuickReport über QRCSVFilter so etwas realisieren kann.
Hast Du ne Ahnung wie das funktionieren könnte?

Gruß
Gabi


mkinzler - Mo 13.03.06 19:16

Ich kenn zwar QR habe damit aber diese Kompoenente auch noch nie benutzt. Da ich nun D10 verwende und dort kein QR mehr dabei ist, kann ichs auch nicht Testen.

Aber die direkte Ausgabe mit WriteLn in eine Datei ( TextFile) sollte aber funktionieren. Was funktioniert nicht? Fehlermeldung?


raiguen - Mo 13.03.06 19:27

user profile icongamoes hat folgendes geschrieben:
mit Writeln klappt das bei mir noch nicht so ganz.
Hab jetzt eben gesehen, dass man auch mit QuickReport über QRCSVFilter so etwas realisieren kann.
Hast Du ne Ahnung wie das funktionieren könnte?

Gruß
Gabi


Moin :-)

Wieso klappt's nicht mit writeln? Woran hakt es? Prinzipiell isses mit Ausgabe in eine Textdatei wesentlich schneller als erst umständlich den QR zu bemühen..

Gruß

//EDIT ein bissl zu spät :-(


gamoes - Mo 13.03.06 22:38

Ich glaube, mir fehlt da noch was.

Ich hab zuerst die query gefüllt und dann anschließend den Quelltext aus Deinem Beispiel dahinter gesetzt.
Dann bekomm ich aber ne Exception. Könnte sein, dass mein Select noch nicht korrekt ist.
Beim debuggen, bleibt er immer beim Open der query stehen.

Ich hab geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
qry_TEinldg.ConnectionString:=ADO_PROVIDER;
   qry_TEinldg.Close;
   qry_TEinldg.SQL.Clear;
   qry_Einldg.SQL.Add('SELECT * FROM anwaerter WHERE testeinladung=1');
   qry_Ausnr.Open;

   s := qry_TEinldg.Fields.FieldByNumber(0).AsString  
   for i := 1 to TEinldg.FieldCount-1  do begin  
      s := s + ';' + TEinldg.Fields.FieldByNumber(i).AsString;  
   end;  
   WriteLn ( f, s);


Wie trage ich da jetzt ein, in welche Datei geschrieben werden soll. Ich muss doch eigentlich den Pfad und den Namen der Datei angeben oder?

Gruß
Gabi

P.S. Sorry bin noch ziemliche Delphi-Anfängerin und brauch ein bisschen, bis ich Tips umgesetzt habe

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt


mkinzler - Mo 13.03.06 22:47

Zitat:
Wie trage ich da jetzt ein, in welche Datei geschrieben werden soll. Ich muss doch eigentlich den Pfad und den Namen der Datei angeben oder?

Du mußt am Anfang eine Variable vom Typ TextFile deklarieren. Ich nenne sie mal F
Dieser wird dann mit


Delphi-Quelltext
1:
AssignFile( F, 'liste.csv');                    


Diese wird dann mit ReWrite(f); zum Schreiben geöffnet. Nun kann man mit write/writeln in sie schreiben.

Am Ende wird die datei mit CloseFile( F); wieder geschlossen.

[edit]Eigenen Sttuss korrigiert: Datei zum Schreiben Rewrite nicht Reset[/edit]


gamoes - Mo 13.03.06 23:05

ok. Das hatte mir noch gefehl.
Werd ich probieren.
Und s muss als String deklariert werden am Anfang?

Gruß
Gabi


mkinzler - Mo 13.03.06 23:06

Ja.


raiguen - Mi 15.03.06 12:47

Moin :-)

Wenn ich die Verwirrung komplett machen darf ;-)
@mkinzler: ReWrite(f) erstellt eine neue Datei ( im o.a. Beispiel liste.csv), wobei eine bereits vorhandene gleichnamige Datei gelöscht wird. Logischerweise kann in diese Datei nur geschrieben werden ;-)
Reset(f) öffnet eine vorhandene Datei zum Lesen und Schreiben.


[quote="user profile icongamoes"]

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
qry_TEinldg.ConnectionString:=ADO_PROVIDER;
   qry_TEinldg.Close;
   qry_TEinldg.SQL.Clear;
   qry_TEinldg.SQL.Add('SELECT * FROM anwaerter WHERE testeinladung=1');
   qry_Ausnr.Open;  //--soll wohl qry_Einldg sein oder??

   s := qry_TEinldg.Fields.FieldByNumber(0).AsString  
   for i := 1 to qry_TEinldg.FieldCount-1  do begin  
      s := s + ';' + qry_TEinldg.Fields.FieldByNumber(i).AsString;  
   end;  
   WriteLn ( f, s);

Hab mir erlaubt, die gekennzeichneten Korrekturen einzubauen ;-)

Gruß


gamoes - Do 16.03.06 13:51

Vielen Dank für die Korrekturen.
Aber leider klappt es trotzdem nicht. Habe jetzt folgenden Quelltext:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
**********************************************************
procedure Tfrm_AzubiTesteinladung.bt_DruckenTestClick(Sender: TObject);
var s: String;
    F: TextFile;
    i: Integer;
begin
   qry_TEinldg.ConnectionString:=ADO_Provider;
   qry_TEinldg.Close;
   qry_TEinldg.SQL.Clear;
   qry_TEinldg.SQL.Add('SELECT * FROM anwaerter WHERE testeinladung=0 AND ausschrnr='#39+dbc_AusschrNr.Text+#39);
   qry_TEinldg.Open;

   s:= qry_TEinldg.Fields.FieldByNumber(0).AsString;
   for i := 1 to qry_TEinldg.FieldCount-1 do begin
   s:= s + ';' + qry_TEinldg.Fields.FieldByNumber(i).AsString;
   end;
   AssignFile(F, '.\docs\einladun.dat');
   Reset(F);
   Writeln(F,s);
   CloseFile(f);
end;

***************************************

Bei der Zeile: s:= qry_TEinldg.Fields.FieldByNumber(0).AsString;
bleibt der Compiler mit stehen mit der Fehlermeldung:
EAccessViolation Zugriffsverletzung bei Adresse....

Gruß
Gabi

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt


mkinzler - Do 16.03.06 14:24

Versuchs mal mit:

Delphi-Quelltext
1:
2:
s:= qry_TEinldg.Fields.FieldByNumber(1).AsString;
for i := 2 to qry_TEinldg.FieldCount do begin


Meinen Fehler mit dem Reset anstatt dem Rewrite mußt du auch noch korrigieren


gamoes - Do 16.03.06 19:47

Besten Dank, das läuft jetzt fehlerfrei.
Momentan hab ich zwar in der csv-Datei nur ;;;;;;; stehen, aber das könnte an meinen SELECT liegen. Muss ich jetzt mal prüfen.

Gruß
Gabi


gamoes - Do 16.03.06 20:02

Jetzt bekomme ich die csv-Datei zwar gefüllt, aber leider nur mit einem Datensatz. Muss da vielleicht noch ein Append dazu, damit er die die weiteren Datensätze anhängt?

Gruß
Gabi


mkinzler - Do 16.03.06 21:05

Nein, füg mal bei Zeile 12:

Delphi-Quelltext
1:
2:
3:
qry_TEinldg.First;
while not qry_TEinldg.eof do
begin

und vor dem CloseFile

Delphi-Quelltext
1:
  end;                    

ein.

Nun wird für jede Zeile der Abfrage eine csv-zeile erzeugt.

Der vorige Fehler kamm daher das der Index bei FieldByNumber() nicht der Index der Felder des Queries (beginnt bei 0) sondern der Index der Datenbanktabelle( beginnt bei 1) war.


gamoes - Do 16.03.06 22:38

Das führt leider zu folgender Fehlermeldung:

EInOuterException. Meldung: E/A-Fehler 32

Gruß
GAbi


mkinzler - Do 16.03.06 22:50

Ich habe noch ein paar Korrekturen gemacht:
-AssignFile und Rewrite vor die Schleife
-Next eingefügt

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
**********************************************************
procedure Tfrm_AzubiTesteinladung.bt_DruckenTestClick(Sender: TObject);
var s: String;
    F: TextFile;
    i: Integer;
begin
   qry_TEinldg.ConnectionString:=ADO_Provider;
   qry_TEinldg.Close;
   qry_TEinldg.SQL.Clear;
   qry_TEinldg.SQL.Add('SELECT * FROM anwaerter WHERE testeinladung=0 AND ausschrnr='#39+dbc_AusschrNr.Text+#39);
   qry_TEinldg.Open;
   qry_TEinldg.First;
   AssignFile(F, '.\docs\einladun.dat');
   Rewrite(F);
   while not qry_TEinldg.Eof() do
   begin
     s:= qry_TEinldg.Fields.FieldByNumber(1).AsString;
     for i := 2 to qry_TEinldg.FieldCount do 
     begin
       s:= s + ';' + qry_TEinldg.Fields.FieldByNumber(i).AsString;
     end;
     Writeln(F,s);
     qry_TEinldg.Next;
   end;
   CloseFile(f);
end;

***************************************


gamoes - Do 16.03.06 23:52

Danke das hat jetzt funktioniert, alle meine Datensätze stehen nun zeilenweise in der csv-Datei.

Noch eine Frage: Was ich dort jetzt nicht stehen habe sind die Spaltenüberschriften. Wie bekomm ich denn die in die csv-Datei?

Gruß
Gabi


mkinzler - Fr 17.03.06 09:42

Hallo Gabi,

füge an Zeile 15 folgendes ein:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
     s:= qry_TEinldg.Fields.FieldByNumber(1).FieldName;
     for i := 2 to qry_TEinldg.FieldCount do 
     begin
       s:= s + ';' + qry_TEinldg.Fields.FieldByNumber(i).FieldName;
     end;
     Writeln(F,s);


gamoes - Fr 17.03.06 12:51

Hallo Markus,
tausend Dank, jetzt sieht meine csv-Datei genau so aus wie ich sie brauche.

Viele Grüße
Gabi


mkinzler - Fr 17.03.06 12:57

Gern geschehen!