Hallo ich habe folgendes Problem zu lösen, ich muß Daten aus verschiedenen dBase-Dateien in eine Interbasedatenbank importieren. Dazu habe ich mir ein Filterprogramm geschrieben. Aus der IBTabelle (Filter) werden für jeden Importfilter die Parameter geladen, Import Typ (dBase, Access, Excel ..), der jeweilige Pfad und die entsprechende Tabelle und eine SQL-Anweisung für die Auswahl bestimmter Daten. Daraus wird dann jeweils eine entsprechende ADOConnection sowie eine ADOQuery konfiguriert.
Nun soll in regelmäßigen abständen die Filterdatei durchlaufen werden, und
wenn eine neue Version einer Datei vorhanden ist (Dateidatum), dann soll dieser Filter aktievert werden und die Daten importiert.
Um beim Importlauf den jeweiligen Rechner nicht zu blockieren, können schon mal einige 100000 Datensätze sein, habe ich die ganze Sache in einem
Thread verpackt. Läuft alles wunderbar, nur wenn Sie am Importfilter die Datenquelle - spriche eine SQL-Anweisung auf die nächste dBase-Datei ausgeführt werden soll, bleibt das ergebnis leer. Auch wenn der Durchgang
abgelaufen ist, kann ich auf die ADOQuery nicht mehr zugreifen. Erst wenn ich das Programm neu starte funktioniert es wieder.
// ************************************************** *********** //
// *** Thread-Anweisungen *** //
// ************************************************** *********** //
constructor TDBThread.Create(xZielDB:TIBDatabase;xTA:TIBTransa ction;xQuellDB:TADOConnection;
xFilterTbl:TIBTable;xQuellSQL:TADOQuery;xZielTbl:T IBTable;xFilterID:Integer);
begin
inherited Create(True);
FTA:= xTA; // Transaktion erstellen
FDBZiel:=xZielDB; // Datenbankverbindung herstellen
FDBQuelle:=xQuellDB; // Ado-Connection herstellen
FFilter:=xFilterTbl; // Filtertabellen definieren und Filter suchen
with FFilter do begin
Database:=FDBZiel;
TableName:='AFILTER';
Active:=True;
end;
FQuelle:=xQuellSQL; // Quelltabelle festlegen
FZiel:=xZielTbl; // Zieltabelle festlegen
FProgress:=0;
MaxAnz :=0;
Start :=0;
FreeOnTerminate:=True;
Resume;
end;
procedure TDBThread.Execute;
begin
CoInitialize(nil);
Try
Synchronize(ShowUpdateEin);
StartUpdate;
finally
CoUninitialize;
Synchronize(ShowUpdateAus);
end;
end;
procedure TDBThread.StartUpdate;
var xID:integer;
begin
// Durchlauf der einzelnen Filter;
FFilter.First;
for xID:=1 to FFilter.RecordCount do
begin
SetFilterParameter;
Synchronize(ShowProgress);
SchreibeDaten;
FFilter.Next;
end;
end;
// hier sollen nachher die Daten in die IB-Tabelle geschrieben werden
procedure TDBThread.SchreibeDaten;
begin
FProgress:=0;
MaxAnz := FQuelle.RecordCount;
Start :=0;
FQuelle.First;
while not FQuelle.Eof do
begin
FProgress:=Round(Start/((MaxAnz-1)/100));
Start:=Start+1;
Synchronize(ShowProgress);
FQuelle.Next;
end;
end;
// hier wird zu jemdem Filter die Datenbankeigenschaften gesetzt
procedure TDBThread.SetFilterParameter;
var xListSQL:TStringList;
begin
xListSQL:=TStringList.Create;
// Quelldatenbank definieren
with FDBQuelle do begin
FDBQuelle.Connected:=false;
FDBQuelle.Provider:='Microsoft.Jet.OLEDB.4.0';
FDBQuelle.Properties['Data Source'].Value :=FFilter.FieldByName('IMPORTDATEI').Value;
case FFilter.FieldByName('IMPROTTYP').Value of
2: Properties['Extended Properties'].Value := 'dBASE III';
3: Properties['Extended Properties'].Value := 'Excel 8.0';
end;
FDBQuelle.LoginPrompt:=False;
Connected:=True;
end;
// Quelltabelle festlegen
with FQuelle do begin
Close;
Connection:=FDBQuelle;
xListSQL.Assign(FFilter.FieldByName('SQLABFRAGE')) ;
SQL:=xListSQL;
Open;
Nun soll in regelmäßigen abständen die Filterdatei durchlaufen werden, und
wenn eine neue Version einer Datei vorhanden ist (Dateidatum), dann soll dieser Filter aktievert werden und die Daten importiert.
Um beim Importlauf den jeweiligen Rechner nicht zu blockieren, können schon mal einige 100000 Datensätze sein, habe ich die ganze Sache in einem
Thread verpackt. Läuft alles wunderbar, nur wenn Sie am Importfilter die Datenquelle - spriche eine SQL-Anweisung auf die nächste dBase-Datei ausgeführt werden soll, bleibt das ergebnis leer. Auch wenn der Durchgang
abgelaufen ist, kann ich auf die ADOQuery nicht mehr zugreifen. Erst wenn ich das Programm neu starte funktioniert es wieder.
// ************************************************** *********** //
// *** Thread-Anweisungen *** //
// ************************************************** *********** //
constructor TDBThread.Create(xZielDB:TIBDatabase;xTA:TIBTransa ction;xQuellDB:TADOConnection;
xFilterTbl:TIBTable;xQuellSQL:TADOQuery;xZielTbl:T IBTable;xFilterID:Integer);
begin
inherited Create(True);
FTA:= xTA; // Transaktion erstellen
FDBZiel:=xZielDB; // Datenbankverbindung herstellen
FDBQuelle:=xQuellDB; // Ado-Connection herstellen
FFilter:=xFilterTbl; // Filtertabellen definieren und Filter suchen
with FFilter do begin
Database:=FDBZiel;
TableName:='AFILTER';
Active:=True;
end;
FQuelle:=xQuellSQL; // Quelltabelle festlegen
FZiel:=xZielTbl; // Zieltabelle festlegen
FProgress:=0;
MaxAnz :=0;
Start :=0;
FreeOnTerminate:=True;
Resume;
end;
procedure TDBThread.Execute;
begin
CoInitialize(nil);
Try
Synchronize(ShowUpdateEin);
StartUpdate;
finally
CoUninitialize;
Synchronize(ShowUpdateAus);
end;
end;
procedure TDBThread.StartUpdate;
var xID:integer;
begin
// Durchlauf der einzelnen Filter;
FFilter.First;
for xID:=1 to FFilter.RecordCount do
begin
SetFilterParameter;
Synchronize(ShowProgress);
SchreibeDaten;
FFilter.Next;
end;
end;
// hier sollen nachher die Daten in die IB-Tabelle geschrieben werden
procedure TDBThread.SchreibeDaten;
begin
FProgress:=0;
MaxAnz := FQuelle.RecordCount;
Start :=0;
FQuelle.First;
while not FQuelle.Eof do
begin
FProgress:=Round(Start/((MaxAnz-1)/100));
Start:=Start+1;
Synchronize(ShowProgress);
FQuelle.Next;
end;
end;
// hier wird zu jemdem Filter die Datenbankeigenschaften gesetzt
procedure TDBThread.SetFilterParameter;
var xListSQL:TStringList;
begin
xListSQL:=TStringList.Create;
// Quelldatenbank definieren
with FDBQuelle do begin
FDBQuelle.Connected:=false;
FDBQuelle.Provider:='Microsoft.Jet.OLEDB.4.0';
FDBQuelle.Properties['Data Source'].Value :=FFilter.FieldByName('IMPORTDATEI').Value;
case FFilter.FieldByName('IMPROTTYP').Value of
2: Properties['Extended Properties'].Value := 'dBASE III';
3: Properties['Extended Properties'].Value := 'Excel 8.0';
end;
FDBQuelle.LoginPrompt:=False;
Connected:=True;
end;
// Quelltabelle festlegen
with FQuelle do begin
Close;
Connection:=FDBQuelle;
xListSQL.Assign(FFilter.FieldByName('SQLABFRAGE')) ;
SQL:=xListSQL;
Open;
Comment