Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Excel aus einem Thread fernsteuern (https://www.delphipraxis.net/43769-excel-aus-einem-thread-fernsteuern.html)

pero.s 8. Apr 2005 12:53


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:
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
Delphi-Quellcode:
  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.

Vjay 8. Apr 2005 13:12

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.

pero.s 19. Apr 2005 00:05

Re: Excel aus einem Thread fernsteuern
 
Treffer, danke.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz