Helau, Euer Forum hat einen neuen Delphianer!
Und dieser hat seit 2 Tagen ein für ihn nicht lösbares Problem?!?
Ich habe viel recherchiert, komme aber ohne Eure Hilfe nicht weiter.
Ich hoffe, ich poste im richtigen Bereich, aber dieser schien mir aufgrund der
VCL am passensten.
Aufgabe:
Ich habe eine multithreaded-Anwendung. Nun möchte ich in Excel 2000 loggen.
Lösungsansatz:
Um mich nicht mit dem Multithreaded-Appartment-Model von
COM herumschlagen zu müssen, schreibe ich die Log-Einträge in eine Queue. In der Thread.Execute-Methode werden die Einträge aus der Queue geholt und über
COM in die Excel-Datei geschrieben. Es gibt nur eine Instanz des Logging-Threads.
- Am Anfang der Thread.Execute wird das
OLE-Objekt erzeugt
- In der while not self.Terminated werden die Einträge aus der Queue geschrieben
- Wenn der Thread terminiert wird, wird Excel beendet
Problem:
Wenn ich Excel aus dem Thread schließen möchte, bleibt es weiterhin im Taskmanager - trotz Xls:= Unassigned.
Um die Verwirrung zu vervollständigen (wie im Codebeispiel):
- Ich schließe Excel im Code nicht per Xls.Application.Quit sondern sage Xls.Visible:= true;
- Beende meine Anwendung - Der Thread wird terminiert
- Nun beende ich Excel manuell über die Excel-Oberfläche -> Excel bleibt auch weiterhin im Taskmanager
- Führe ich die Anweisungen aus dem
GUI-Thread aus durch, ist alles i.O.
Ich bin verzweifelt und komme einfach nicht mehr weiter. Ich hoffe, dass mir jemand von euch auf die Sprünge helfen kann.
Vielen Dank!!!
Totti
Hier die vereinfachte Execute-Methode des Threads:
Delphi-Quellcode:
procedure TLoggingExcel.Execute;
var
fExl, fSht: Variant;
begin
inherited;
CoInitializeEx(
nil,0);
fExl:=CreateOleObject('
Excel.Application');
fExl.Application.SheetsInNewWorkbook:= 1;
fExl.Workbooks.Add;
fExl.Sheets.Add;
fSht:= fExl.Sheets[1];
fSht.
Name := '
Log Sprachverständlichkeit';
//fileExcelLog;
fExl.ActiveWorkbook.SaveAs('
C:\test.xls');
while self.Terminated=false
do
begin
fSht.Cells[1,1].Value:= '
COM plus Threads ist mir suspekt';
fExl.ActiveWorkbook.Save;
end;
fExl.Visible:=true;
fExl.ActiveWorkbook.Saved:= true;
//fExl.Application.Quit;
hSht:= Unassigned;
fExl:= Unassigned;
CoUnInitialize;
end;