AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Excel in einer Komponente einbinden generell machbar?
Thema durchsuchen
Ansicht
Themen-Optionen

Excel in einer Komponente einbinden generell machbar?

Ein Thema von BAMatze · begonnen am 22. Jun 2009 · letzter Beitrag vom 29. Jun 2009
Antwort Antwort
Seite 2 von 2     12   
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#11

Re: Excel in einer Komponente einbinden generell machbar?

  Alt 29. Jun 2009, 10:13
Hallo wie versprochen stelle ich hier mal einen vereinfachten Quellcode zur Verfügung, bei dem in einer Komponente des Typs TWinControl Excel mit eingebunden ist.
Die Variante, welche ich hier zur Verfügung stelle, läuft allerdings nur mit Office2003 ansonsten müssen einfach ein paar Codestellen angepasst werden.

Delphi-Quellcode:
unit KomponentenUnit;

interface

uses Windows, SysUtils, Dialogs, Messages, Controls, Classes,StdCtrls, ExcelXP, Variants,
     ActiveX;

Type TMyComponentWithExcel = Class(TWinControl)
  private
    FExcelApplication: TExcelApplication;
    FExcelWorkbook: TExcelWorkbook;
    FExcelWorksheet: TExcelWorksheet;
    FExcelWert: Variant;
    FEdEingabe: TEdit;
    FBtSpeichern, FBtLoeschen: TButton;

    function CreateEdit(PosX, PosY: integer): TEdit;
    function CreateButton(PosX, PosY: integer; Text: string): TButton;

    function ProgIDExists(const ProgID:WideString):Boolean;
    function ExcelVerfuegbarkeit: boolean;

    procedure OnEditChange(Sender: TObject);
    procedure OnLoeschenClick(Sender: TObject);
    procedure OnSpeichernClick(Sender:TObject);

    procedure CreateTestdatei(sName: string);
    procedure openTestdatei(sName: string);
    procedure WriteEdit;

  protected
    procedure CreateWnd; override;
  published

  public
    constructor create(AOwner: TComponent); override;
    destructor destroy; override;
End;

implementation

constructor TMyComponentWithExcel.create(AOwner: TComponent);
begin
  inherited create(AOwner);
  // Verhinder, dass andere Controls auf die Komponente gezogen werden kann
  Controlstyle := Controlstyle - [csAcceptsControls];

  Visible := true;
  Width := 200;
  Height := 100;

end;

destructor TMyComponentWithExcel.Destroy;
begin
  try
    if Enabled then
      begin
        if not (csDesigning in Self.ComponentState) then FExcelWorkbook.Close(true); // Speichert die Änderungen in Excel
        FExcelWorksheet.Free;
        FExcelWorkbook.Free;
        FExcelApplication.Free;
      end;
  finally
    FEdEingabe.Free;
    FBtSpeichern.Free;
    FBtLoeschen.Free;
    inherited Destroy;
  end;
end;

function TMyComponentWithExcel.CreateEdit(PosX: Integer; PosY: Integer): TEdit;
begin
  result := TEdit.Create(nil);
  result.Parent := Self;
  result.Left := PosX;
  result.Top := PosY;
  result.Width := 190;
  result.Height := 20;
end;

function TMyComponentWithExcel.CreateButton(PosX: Integer; PosY: Integer; Text: string): TButton;
begin
result := TButton.Create(nil);
  result.Parent := Self;
  result.Left := PosX;
  result.Top := PosY;
  result.Height := 20;
  result.Width := 80;
  result.Caption := Text;
  result.Enabled := false;
end;

procedure TMyComponentWithExcel.CreateTestdatei(sName: string);
var sOrdner: string;
    iUserLCID: integer;
begin
  iUserLCID := GetUserDefaultLCID;
  FExcelApplication := TExcelApplication.Create(Nil);
  FExcelApplication.Workbooks.Add(emptyparam, iUserLCID);
  FExcelWorkbook := TExcelWorkbook.create(Nil);
  FExcelWorkbook.ConnectTo(FExcelApplication.ActiveWorkbook as ExcelWorkbook);
  FExcelWorkbook.Worksheets.Add(emptyParam, emptyParam, emptyParam, emptyParam, iUserLCID);
  FExcelWorksheet := TExcelWorksheet.create(Nil);
  FExcelWorksheet.ConnectTo(FExcelWorkbook.ActiveSheet as ExcelWorksheet);
  FExcelWorkbook.Close(true,sName, emptyParam, iUserLCID); // Speichert die Änderungen in Excel }
  FExcelWorksheet.Free;
  FExcelWorkbook.Free;
  FExcelApplication.Free;
end;

procedure TMyComponentWithExcel.openTestdatei(sName: string);
var iUserLCID: integer;
    DWResult: DWord;
begin
  iUserLCID := GetUserDefaultLCID;
  // Wenn die Datenbank extern über Excel geöffnet ist dann wird sie geschlossen.
  // wenn diese Datei nicht geschlossen wird, dann kommt es zu einer Exception!!!
  if FindWindow('XLMain','Microsoft Excel - ' + 'Test.xls') <> 0 then
     SendMessageTimeout(FindWindow('XLMain','Microsoft Excel - ' + 'Test.xls'), WM_CLOSE, 0, 0,
     SMTO_ABORTIFHUNG or SMTO_NORMAL, 5000, DWResult);
  FExcelApplication := TExcelApplication.Create(Nil);
  FExcelWorkbook := TExcelWorkbook.create(Nil);
  FExcelWorksheet := TExcelWorksheet.create(Nil);
  // vorhandener Exceldatei laden !!! wichtig !!! Die Anzahl der emtyParam ist Office-Versions abhängig
  FExcelApplication.Workbooks.Open(sName, emptyParam, emptyParam, emptyParam, emptyParam,
                                   emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam,
                                   emptyParam, emptyParam, iUserLCID);
  // false = Excel soll NICHT angezeigt werden// true Excel soll angezeigt werden
  FExcelApplication.visible[iUserLCID] := true;
  // verbinden des Workbooks und des Worksheets mit der in der exc geladenen Datei
  FExcelWorkbook.ConnectTo(FExcelApplication.ActiveWorkbook);
  FExcelWorksheet.ConnectTo(FExcelWorkbook.ActiveSheet as ExcelWorksheet);
end;

procedure TMyComponentWithExcel.WriteEdit;
var sTemp: string;
begin
  // Überprüfen des Wertes in A1
  sTemp := FExcelWorksheet.Cells.Item[1,1];
  if sTemp <> 'then
    begin
      FEdEingabe.Text := sTemp;
      FBtLoeschen.Enabled := true;
    end
  else FEdEingabe.Text := 'empty';
end;

procedure TMyComponentWithExcel.OnEditChange(Sender: TObject);
var sTemp: string;
begin
  if (FEdEingabe.Text <> '') and (FEdEingabe.Text <> 'empty') then
    begin
      sTemp := FExcelWorksheet.Cells.Item[1,1];
      if FEdEingabe.Text <> sTemp then
        begin
          FBtLoeschen.Enabled := true;
          FBtSpeichern.Enabled := true;
        end
      else
        begin
          FBtLoeschen.Enabled := true;
          FBtSpeichern.Enabled := false;
        end;
    end
  else
    begin
      FBtLoeschen.Enabled := false;
      FBtSpeichern.Enabled := false;
    end;
end;

procedure TMyComponentWithExcel.OnLoeschenClick(Sender: TObject);
begin
  FEdEingabe.Text := 'empty';
  FExcelWorksheet.Cells.Item[1,1] := '';
end;

procedure TMyComponentWithExcel.OnSpeichernClick(Sender: TObject);
begin
  FBtSpeichern.Enabled := false;
  FExcelWorksheet.Cells.Item[1,1] := FEdEingabe.Text;
end;

function TMyComponentWithExcel.ProgIDExists(const ProgID:WideString):Boolean;
var
   tmp : TGUID;
begin
   Result := Succeeded(CLSIDFromProgID(PWideChar(ProgID), tmp));
end;

function TMyComponentWithExcel.ExcelVerfuegbarkeit: boolean;
begin
  // Es muss das Office-Packet 2003 auf dem Rechner installiert sein, damit diese
  // Komponente funktioniert. Dies ist nötig, da in jeder Version des Office-Packetes
  // unterschiedlich viele Parameter zum öffnen einer Datei benötigt werden.
  // Wenn kein oder ein falsches Office-Packet installiert ist, wird die Komponente
  // in der CreateWnd-Procedure disabled.
  if ProgIDExists('Excel.Application.11') then result := true
  else result := false;
end;

procedure TMyComponentWithExcel.CreateWnd;
var sOrdner: string;
begin
  inherited createWnd;
  FEdEingabe := CreateEdit(5,10);
  FEdEingabe.OnChange := OnEditChange;
  FBtSpeichern := CreateButton(5,50,'Speichern');
  FBtSpeichern.OnClick := OnSpeichernClick;
  FBtLoeschen := CreateButton(100,50,'Löschen');
  FBtLoeschen.OnClick := OnLoeschenClick;
  // Dieser Teil wird nur zur Laufzeit ausgeführt
  if not (csDesigning in Self.ComponentState) then
    begin
      if Excelverfuegbarkeit then
        begin
          sOrdner := ExtractFilePath(ParamStr(0));
          if not FileExists(sOrdner + 'Test.xls') then CreateTestdatei(sOrdner + 'Test.xls');
          // Laden der Datei und eintragen des Wertes aus A1 in das Edit
          // je nach Eintrag in A1 Button Löschen freigeben.
          openTestdatei(sOrdner + 'Test.xls');
          writeEdit;
        end
      else
        begin
          Showmessage('Komponente kann leider nicht aktiviert werden, da sie nicht das OfficePacket 2003 installiert haben');
          Enabled := false;
        end;
    end;
end;

end.
Die in den vorher angesprochenen Fehler waren Folgen der nicht Beachtung von csDesigning. Nachdem ich die 2 Abfragen in CreateWND und Destroy eingebaut hatte, lief die Komponete Fehlerfrei bei mir.

Wie gesagt, sind sicherlich noch Verbesserungen möglich und würde mich über Anregungen freuen.

MfG und Vielen Dank
BAMatze
Angehängte Dateien
Dateityp: zip excel_in_twincontrol_718.zip (34,2 KB, 10x aufgerufen)
2. Account Sero
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 22:36 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