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:
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
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.
Wenn ich nun diese Routine in einen Thread integriere und die drei Elemente
ExclApp,
ExclDoc und
ExclSht manuell mit
ExclApp := TExcelApplication.Create(FormMain); //Beispiel
erzeuge und dann irgendeinen Aufruf via
ExclApp starte, bekomme ich einen Laufzeitfehler der besagt, dass
CoInitialize nicht aufgerufen wurde.
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:
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; //...
gegangen bin - mit selbem Ergebnis.
Was mache ich falsch?
P.S.: Wenn Interesse am ganzen Projekt besteht, so kann ich das hier mit hereinstellen.
Pero S.