AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Excel aus einem Thread fernsteuern

Ein Thema von pero.s · begonnen am 8. Apr 2005 · letzter Beitrag vom 19. Apr 2005
Antwort Antwort
pero.s

Registriert seit: 6. Feb 2005
Ort: Konstanz
4 Beiträge
 
Delphi 2006 Professional
 
#1

Excel aus einem Thread fernsteuern

  Alt 8. Apr 2005, 13:53
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.
  Mit Zitat antworten Zitat
Vjay

Registriert seit: 2. Dez 2003
Ort: Berlin/Eschede
481 Beiträge
 
Delphi 7 Professional
 
#2

Re: Excel aus einem Thread fernsteuern

  Alt 8. Apr 2005, 14:12
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.
Wer später bremst ist eher tot.
  Mit Zitat antworten Zitat
pero.s

Registriert seit: 6. Feb 2005
Ort: Konstanz
4 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Excel aus einem Thread fernsteuern

  Alt 19. Apr 2005, 01:05
Treffer, danke.
Pero S.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:10 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