![]() |
Excel aus einem Thread fernsteuern
Hallo allerseits.
Ich habe mir ein kleines Programm geschrieben, das mir Daten in eine Excel-Tabelle schiebt und formatiert. Das hat dann auch alles wunderbar funktioniert. Und, da alles funktioniert wollte ich als letzten Schritt die Routine, die den Export tätigt, in einen separaten Thread bauen, da ich nicht unnötig das Hauptformular auslasten möchte. Die Routine ist:
Delphi-Quellcode:
Wie man sehen kann, ist die Routine voll in das Programm mit anderen Komponenten integriert und ich habe gegen Ende der Routine den Start des Threads auskommentiert.
uses
Windows, ExcelXP, OleServer; (* - Im Objekt deklariert ExclApp: TExcelApplication; ExclDoc: TExcelWorkbook; ExclSht: TExcelWorksheet; *) procedure TFormMain.ActionExpsExecute(Sender: TObject); var lcid, i, j: LongInt; EAP: _Application; EWB: _Workbook; EWS: _Worksheet; EFM, ECL: OleVariant; begin lcid := LOCALE_USER_DEFAULT; ActionStop.Enabled := ListView.Items.Count > 0; ActionScan.Enabled := not ActionStop.Enabled; ActionExps.Enabled := ActionScan.Enabled; if ActionStop.Enabled then begin PBarRow.Position := 0; PBarRow.Max := ListView.Items.Count - 2; PBarAll.Position := 0; PBarAll.Max := ListView.Columns.Count - 1; Refresh; ExclApp.Connect; ExclApp.Visible[lcid] := True; EWB := ExclApp.Workbooks.Add('', lcid); ExclDoc.ConnectTo(EWB); ExclDoc.Activate; EWS := ExclDoc.Activesheet as _Worksheet; ExclSht.ConnectTo(EWS); i := 1; while i < ListView.Columns.Count do begin PBarAll.Position := i; PBarAll.Refresh; ECL := Chr(64 + i); if (Length(ListView.Columns[i].Caption) = 0) or (LowerCase(ListView.Columns[i].Caption) = 'text') then EFM := NS_AT else EFM := ListView.Columns[i].Caption; ExclSht.Range[ECL + '1', ECL + IntToStr(ListView.Items.Count)].NumberFormat := EFM; j := 0; while j < ListView.Items.Count do begin if i <= ListView.Items[j].SubItems.Count then begin PBarRow.Position := j; PBarRow.Refresh; ECL := WideString(Chr(64 + i) + IntToStr(j + 1)); EFM := WideString(ListView.Items[j].SubItems[i - 1]); ExclSht.Range[ECL, ECL].Value2 := EFM; end; j := j + 1; end; ECL := Chr(64 + i); //ExclSht.Range[ECL, ECL].AutoFit; i := i + 1; end; (*try Exporter := TTrExExps.Create(not ActionStop.Enabled); Exporter.FreeOnTerminate := ActionStop.Enabled; Exporter.OnTerminate := TrExOnTerminate; except end;*) end; end; //ActionExpsExecute Wenn ich nun diese Routine in einen Thread integriere und die drei Elemente ExclApp, ExclDoc und ExclSht manuell mit
Delphi-Quellcode:
erzeuge und dann irgendeinen Aufruf via ExclApp starte, bekomme ich einen Laufzeitfehler der besagt, dass CoInitialize nicht aufgerufen wurde.
ExclApp := TExcelApplication.Create(FormMain); //Beispiel
Ich habe das Ganze auch ohne die drei Elemenete ExclApp, ExclDoc und ExclSht versucht, indem ich nur über _Application, _Workbook und _Worksheet mit
Delphi-Quellcode:
gegangen bin - mit selbem Ergebnis.
procedure ...
var Unknown: IUnknown; OleRes: HRESULT; begin OleRes := GetActiveObject(CLASS_ExcelApplication, nil, Unknown); if OleRes = MK_E_UNAVAILABLE then EAP := CoExcelApplication.Create else begin OleCheck(OleRes); OleCheck(Unknown.QueryInterface(_Application, EAP)); end; end; //... Was mache ich falsch? P.S.: Wenn Interesse am ganzen Projekt besteht, so kann ich das hier mit hereinstellen. |
Re: Excel aus einem Thread fernsteuern
Hallo, schau mal in die WinAPI-Hilfe unter CoInitialize.
Du musst die Unit Ole2 einbinden und CoInitialize vor dem Excelwork und CoUnInitialize danach aufrufen. Der Grund dafür ist, dass Delphi für den Hauptthread den Aufruf bereits macht, CoInitialize aber Thread-abhängig ist. |
Re: Excel aus einem Thread fernsteuern
Treffer, danke.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz