AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Excel fernsteuerun mit OLE: TExcelChart Objekt
Thema durchsuchen
Ansicht
Themen-Optionen

Excel fernsteuerun mit OLE: TExcelChart Objekt

Ein Thema von RoMe87 · begonnen am 3. Nov 2009 · letzter Beitrag vom 25. Nov 2009
Antwort Antwort
Seite 1 von 2  1 2      
RoMe87

Registriert seit: 11. Okt 2009
Ort: Mannheim
8 Beiträge
 
Delphi 7 Personal
 
#1

Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 3. Nov 2009, 10:06
Hallo alle zusammen!
Folgendes Problem: Überall sehe ich die unterschiedlichsten Methoden, Excel fernzusteuern, Datein ein- oder auszulesen, zu öffnen oder zu speichern. Gut, ich komme jetzt damit zurecht. Nun hab ich aber die Aufgabe, Daten über einen auf ein Diagramm (Liniendiagramm) auszugeben, welches ich vorher definiert hab.
Zu texcelchart habe ich bisher nur spärlich was gefunden. Weder in diesem Forum noch sonstwo im deutsch- und englischsprachigem Raum. Daher hier die Frage: Wie kann ich Daten in ein selbstkonfiguriertes Diagramm ausgeben?

Zur Info: Die Tabelle existiert schon, workbook, worksheet, Daten im worksheet...
Es sollte möglichst als eigenes Worksheet, also nicht in die schon existierende Tabelle ausgegeben werden.

Vielen dank schon im Vorraus!
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 3. Nov 2009, 10:13
Lass dir den Vorgang in Excel als Makro aufzeichen
Markus Kinzler
  Mit Zitat antworten Zitat
RoMe87

Registriert seit: 11. Okt 2009
Ort: Mannheim
8 Beiträge
 
Delphi 7 Personal
 
#3

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 3. Nov 2009, 12:39
Vielen Dank für den Tip.
Leider bringt mir dies recht wenig, weil ich erstens nicht alles so umsetzen kann, wie es in VBA steht und es zweitens bei der methode keine Klasse TExcelChart und _Chart gibt.

Ach ja, noch ne Frage: Was ist der Unterschied zwischen
TExcelWorkbook und _Workbook
TExcelSheet und _Sheet
TExcelChart und _Chart

Wofür nutzt man das eine, und wofür das andere?

Danke schonmal
RoMe
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.859 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 5. Nov 2009, 19:32
Hallo RoMe87,

TExcelWorkbook
TExcelSheet
TExcelChart

sind Komponenten
_Workbook
_Sheet
_Chart

Sind Co-Klassen

Zu Deinem Problem grundsätzlich hat Markus recht, normal versucht man sich einen VBA-Macro zu erstellen um in anschließend in Delphi umzusetzen.

Wenn Du aber sowieso das Diagramm vorliegen hast, würde es sich anbieten das Diagramm in eine Excel-Datei zu speichern und jedes Mal zu laden wenn es gebraucht wird und die geänderten Daten in eine Tabelle schreiben die einen Bezug zum Diagramm hat.

Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
RoMe87

Registriert seit: 11. Okt 2009
Ort: Mannheim
8 Beiträge
 
Delphi 7 Personal
 
#5

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 7. Nov 2009, 10:31
Vielen Dank erstmal für die Hilfe

Ich habe das Diagramm nicht, das soll jedes Mal neu erstellt werden, zusammen mit dem Rest des Workbooks.
Und ich habe leider immernoch keine Ahnung, wie ich alles umsetzen soll, was mir VBA so vorgibt.



Aber danke für die Unterstützung
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.859 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 8. Nov 2009, 00:34
Hallo RoME87,

ich habe Dir mal ein minimales Beispiel zusammen geschrieben.
Das ist eigentlich nur den VBA-Macro in Delphi umgesetzt.

Die Unit comobj wird für die OLE-Automation gebraucht, die Unit ExcelXP wird eingebunden für die Konstanten von Excel (im Beispiel für xlColumnClustered)

Delphi-Quellcode:
unit MainExcel_Tabelle_Diagramm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, comobj, ExcelXP;

type
  TForm1 = class(TForm)
    SG: TStringGrid;
    btDatenNachExcel: TButton;
    btStringGridMitDatenFuellen: TButton;
    procedure btStringGridMitDatenFuellenClick(Sender: TObject);
    procedure btDatenNachExcelClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    vEXCEL: OLEVariant;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btDatenNachExcelClick(Sender: TObject);
var
  z, s: integer;
begin
  try
    vExcel := CreateOleObject('Excel.Application');
  except
    ShowMessage('Excel konnte nicht gestartet werden');
    Exit;
  end;
  vExcel.Visible := TRUE;
  vExcel.Application.Caption:= 'Demo für Diagramm Erstellung';
  vExcel.WorkBooks.Add;
  vExcel.WorkSheets[1].Name := 'Tabelle mit Daten';
  // Ab hier werden die Daten von StringGrid nach Excel exportiert.
  // Zu beachten ist das die erste Zeile/Spalte im StringGrid = 0 ist und
  // bei Excel =1
  for z := 1 to sg.RowCount do
  begin
    for s := 1 to sg.ColCount do
    begin
      vExcel.cells[z, s].Value2 := SG.Cells[s-1, z-1];
    end;
  end;
  // Werte Tabelle in Excel markieren
  vExcel.ActiveWorkbook.WorkSheets['Tabelle mit Daten'].Range['A1','B5'].Select;
  // Neue Diagramm-Seite anlegen
  vExcel.Charts.Add;
  // Diagrammtype auswählen
  vExcel.Charts[1].ChartType:= xlColumnClustered;
  // Die Diagrammseite einen Namen geben
  vExcel.Charts[1].Name := 'Test Diagramm';
  // Aufräumen
  ShowMessage('Excel wird jetzt geschlossen');
  vExcel.ActiveWorkbook.Save;
  vExcel.Quit;
  vExcel:= Unassigned;
end;

procedure TForm1.btStringGridMitDatenFuellenClick(Sender: TObject);
begin
  with SG Do
  begin
    Cells[0,0] := 'Umsatz';
    Cells[1,0] := 'Kosten';
    Cells[0,1] := '500';
    Cells[0,2] := '400';
    Cells[0,3] := '300';
    Cells[0,4] := '800';
    Cells[1,1] := '300';
    Cells[1,2] := '500';
    Cells[1,3] := '900';
    Cells[1,4] := '700';
  end;
end;

end.

Vielleicht Hilft Dir das weiter.
Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
zeras

Registriert seit: 11. Mär 2007
Ort: Saalkreis
1.633 Beiträge
 
Delphi 12 Athens
 
#7

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 8. Nov 2009, 10:44
Ich hatte auch mal vor, mit einem Delphiprogramm Daten in ein Excelsheet einzutragen, aber gibt es da nicht Probleme mit den verschiedenen Excel Versionen, Bsp. Excel95, 97, 2000, 2003, 2007? Dann ist es ja schwierig, zu testen, denn man hat ja meist nicht jedes Excel auf dem Rechner und man weiß meistens nicht, was auf dem Zielrechner für ein Excel installiert ist.
Matthias
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.859 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 8. Nov 2009, 15:01
Hallo zeras,

mit der späten Bindung wie im Beispiel kann man das Problem umgehen. Allerdings kann man in Excel 95 keine Funktionen ausführen die erst bei späteren Versionen vorhanden sind, dieses Problem hat man aber auch bei normaler Excel Benutzung. So sind bei Excel 2007 die Anzahl der zulässigen Zeilen und Spalten wesentlich größer als bei den Vorgängerversionen.

Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
RoMe87

Registriert seit: 11. Okt 2009
Ort: Mannheim
8 Beiträge
 
Delphi 7 Personal
 
#9

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 10. Nov 2009, 14:13
Hallo nochmal!
Erstmal Dank an Chemikus (Ich scheine jedes Mal zu danken, klingt langsam abgedrochen aber ich meine es ernst!)

Der Code hilft sehr gut fürs verständnis. Nur habe ich folgendes Probleme:

Das Diagramm soll in ein neues Sheet, von da aus auf das erste Sheet ("Daten") zugreifen. Es wird mehrmals (zyklisch) aktualisiert(das ist kein Problem DAU bin ich nicht mehr). Der VBA Code lautet in etwa so:

Charts.Add
ActiveChart.ChartType = xlLineMarkers
ActiveChart.SetSourceData Source:=Sheets("Tabelle1").Range("A1")
ActiveChart.SeriesCollection.NewSeries
ActiveChart.SeriesCollection(1).XValues = "=Tabelle1!R1C2:R9C2"
ActiveChart.SeriesCollection(1).Values = "=Tabelle1!R1C1:R9C1"
ActiveChart.SeriesCollection(1).Name = "=""Daten"""
ActiveChart.Location Where:=xlLocationAsNewSheet
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "Daten"
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "X-Achser"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Y_Achse"
End With
ActiveChart.HasDataTable = False
End Sub

Ich kann aber aus irgendeinen Grund Activechart.seriescollection nicht einfach so übernehmen/umschreiben. Gibt mir da Fehlermeldungen zurück, bevor er abstürzt...
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#10

Re: Excel fernsteuerun mit OLE: TExcelChart Objekt

  Alt 20. Nov 2009, 15:50
Die Diskusion ist zwar schon länger her, aber ich werde mal auch meinen Senf dazugeben.

Das hier beschriebene Problem hatte ich auch. Aus einem Programm Daten exportieren, diese dann als Pivottabelle aufbereiten und, wenn von Benutzer gewünscht, als Diagramm darstellen.

Wir haben auch erst späte Bindung benutzt, aber da MS einen im Regen stehen lässt sind wir schnell umgestiegen.

Ich habe einen Excel-Server geschrieben der die kapselt und auf unsere Ansprüche zuschneidet. Leider geht mir der Server noch nicht weit genug, aber man hat ja nie genug Zeit alles auszufeilen.

Für eine größtmögliche Unterstützung benutzen wir eine leicht modifizierte Excel 97 Type Library.

Hier ein paar wichtige Zeilen:
Delphi-Quellcode:
  TExcelServer = class
  private
    {$REGION 'Wrapperklassen'}
    FOwner : TComponent;
    FLCID : Integer;
    FConnected : boolean;
    ExcelApplication : TExcelApplication;
    ExcelWorkbook : TExcelWorkbook;
    ExcelWorksheet : TExcelWorksheet;
    ExcelPivotTables : PivotTables;
    ExcelPivotTable : PivotTable;
    ExcelPivotFields : PivotFields;
    ExcelPivotField : PivotField;
    ExcelPivotDataFields : PivotFields;
    ExcelPivotDataField : PivotField;
    ExcelPivotItems : PivotItems;
    ExcelPivotItem : PivotItem;
    ExcelChart : TExcelChart;
    ExcelChartSeriesCollection : SeriesCollection;
    ExcelChartSeries : Series;
    ExcelChartObjects : ChartObjects;
    ExcelChartObject : ChartObject;

    FbIsAppWbOpen,
    FbIsAppWbNew : boolean;
    {$ENDREGION}

...

    {$REGION 'Workbook -------------------------------------------------------------------'}
    procedure WorkbookNew(Template: xlWBATemplate = xlWBATWorksheet);
    {$ENDREGION}

    {$REGION 'Worksheet ------------------------------------------------------------------'}
    procedure WorksheetNew(Template: xlWBATemplate = xlWBATWorksheet);
    {$ENDREGION}

    {$REGION 'Pivot ----------------------------------------------------------------------'}
    procedure DeselectAllPivotItems(Name : string);

    function GetPivotFormatType(PivotFormatType : TIvuPivotAutoFormatType) : Longword;

    function GetPivotFieldItems(Field : string; F : xlPivotFieldOrientation) : TStrings;
    {$ENDREGION}

    {$REGION 'I/O Hilfe ------------------------------------------------------------------'}
    // übersetzt Row, Col in, für Excel verständliche "Zellenadresse"
    function TranslateCell(Row, Col : integer) : string;

    procedure TranslateRange(fromRow, fromCol, toRow, toCol : integer;
                             var FromCell, ToCell : string);

    function TranslateColumn(Col : integer) : string;

    procedure MacroRun(Name: string); overload;

    // Maximal 18 Argumente Rest wird ignoriert
    procedure MacroRun(Name: string; Args: TStringList); overload;

    // schreibt das Makro Macro in das aktuelle
    procedure MacroSet(Macro : TStringList);
    {$ENDREGION}

...

  public
    constructor Create(AOwner : TComponent; sExcelPath : string);
    destructor Destroy; override;

    {$REGION 'allgemein ------------------------------------------------------------------'}
    function IsRegistered : boolean;
    procedure CloseExcel;
    procedure StartExcel(StartSeperateInstance : boolean = false);
    procedure DisconnectAll;

    procedure OpenFile(sFileName : string);
    procedure NewFile;

    procedure Run(MacroName : string); overload;
    procedure Run(MacroName : string; Argumente : TStringList); overload;

    procedure InsertMacro(Text : TStringList);
    function MacroExsists(MacroName : string = '') : boolean;
    {$ENDREGION}

    {$REGION 'Workbook -------------------------------------------------------------------'}
    procedure OnAppWorkbookOpen(ASender: TObject; const Wb: ExcelWorkbook);
    procedure OnAppWorkbookNew(ASender: TObject; const Wb: ExcelWorkbook);
    procedure SaveActiveWorkbookAs(sFileName : string; TryOverride : boolean = true); overload;
    procedure SaveActiveWorkbookAs; overload;
    procedure SaveActiveWorkbook;
    {$ENDREGION}

...

    {$REGION 'PivotTable -----------------------------------------------------------------'}
    procedure PivotRefresh;
    // Gibt die Nummer des ersten Worksheets zurück, das eine Pivottabelle enthält.
    // ansonsten wird 0 zurückgegeben.
    function PivotFind : integer;

    procedure PivotSet(Source, SheetName : string;
                       fromRowSource, fromColSource,
                       toRowSource, toColSource,
                       fromRowDest, fromColDest,
                       toRowDest, toColDest : integer);

    procedure PivotSet2(Source, SheetName : string;
                       fromRowSource, fromColSource,
                       toRowSource, toColSource : integer;
                       fromRowDest : integer = 1; fromColDest : integer = 1);

    procedure PivotFormatSet(Format : TIvuPivotAutoFormatType);

    function PivotFormatGet(Format : string) : TIvuPivotAutoFormatType;

    procedure SplitPivotChart_Page(withChart : boolean;
                                   Field : string;
                                   FDiagrammtyp : string;
                                   bDublicateFooter : boolean;
                                   Position : THeaderFooterPosition);
    {$ENDREGION}

...

    {$REGION 'Chart ----------------------------------------------------------------------'}
    function FindBuildinChartTypes : TStrings;

    procedure ChartSet(Source, SheetName : string;
                       Charttype : TIvuExcelChartType;
                       fromRowSource, fromColSource,
                       toRowSource, toColSource : integer;
                       fromPivot : boolean = false); overload;

    // nur von Pivot
    procedure ChartSet(Source, SheetName : string;
                       Charttype : TIvuExcelChartType); overload;

    procedure CustomChartSet(Source, SheetName, ChartName : string;
                            fromRowSource, fromColSource,
                            toRowSource, toColSource : integer;
                            fromPivot : boolean = false);

    procedure SetChartTitle(Name : string);
    procedure SetChartXAchse(Name : string);
    procedure SetChartYAchse(Name : string);
    procedure SetChartXAchseCross(At : TIvuExcelChartAxisCross);
    procedure SetChartYAchseCross(At : TIvuExcelChartAxisCross);

    procedure ChartTypeSet(ChartType : TIvuExcelChartType);
    function ChartTypeGet(ChartType : string) : TIvuExcelChartType;

    procedure SetChartNewSeries(XfromRowSource, XtoRowSource, XColSource,
                                YfromRowSource, YtoRowSource, YColSource : integer;
                                Name : string);
    {$ENDREGION}

...
  end;

constructor TExcelServer.Create(AOwner : TComponent; sExcelPath : string);
begin
  //Überprüfung ob Excel auf Rechner installiert ist
  try
    if IsRegistered = false then
      raise EExcelNotInstalled.Create(rcExcelNotInstalled);
  except
    if not SysUtils.FileExists(sExcelPath) then
      raise EExcelNotInstalled.Create(rcExcelNotInstalled);
  end;

  // für Testzwecke
  // raise EExcelNotInstalled.Create(rcExcelNotInstalled);

  FOwner := AOwner;
  ExcelApplication := TExcelApplication.Create(AOwner);
  Sleep(100);

  ExcelWorkbook := TExcelWorkbook.Create(AOwner);
  ExcelWorksheet := TExcelWorksheet.Create(AOwner);
  ExcelPivotTables := nil;
  ExcelPivotTable := nil;
  ExcelChart := TExcelChart.Create(AOwner);
  ExcelChartObjects := nil;
  ExcelChartObject := nil;
  FConnected := false;

  FLCID := GetUserDefaultLCID;
end;

destructor TExcelServer.Destroy;
begin
  try
    try
      ExcelChart.Disconnect;
    finally
      ExcelChart.Free;
    end;
  except
  end;

  try
    try
      ExcelWorksheet.Disconnect;
    finally
      ExcelWorksheet.Free;
    end;
  except
  end;

  try
    try
      ExcelWorkbook.Disconnect;
    finally
      ExcelWorkbook.Free;
    end;
  except
  end;

  try
    try
      ExcelApplication.Disconnect;
    finally
      ExcelApplication.Free;
    end;
  except
  end;

  inherited Destroy;
end;

// allgemein -------------------------------------------------------------------
function TExcelServer.IsRegistered : boolean;
var Reg: TRegistry;
     bVorhanden : boolean;
begin
  bVorhanden := false;
  //Prüfung ob Excel installiert
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_CLASSES_ROOT;
    Reg.Access := KEY_EXECUTE;
    bVorhanden := Reg.KeyExists(cExcelRegKey);
  finally
    Reg.Free;
    result := bVorhanden;
  end;
end;

procedure TExcelServer.StartExcel(StartSeperateInstance : boolean = false);
begin
  FConnected := false;
  try
    if StartSeperateInstance
    then
    begin
      ExcelApplication.ConnectKind := ckNewInstance;
    end
    else
    begin
      ExcelApplication.ConnectKind := ckRunningOrNew;
    end;

    ExcelApplication.Connect;
    ExcelApplication.EnableEvents := true;
    ExcelApplication.OnWorkbookOpen := OnAppWorkbookOpen;
    ExcelApplication.OnNewWorkbook := OnAppWorkbookNew;
// ExcelApplication.UserControl := false;
    ExcelApplication.DisplayAlerts[FLCID] := true;
    {Excel-Arbeitsblätter können Verknüpfungen zu anderen Dateien haben.
     Hier wird der Verknüpfungen-Aktualisieren Dialog unterdrückt}

    ExcelApplication.AskToUpdateLinks[FLCID] := false;
    ExcelApplication.Visible[FLCID] := false; // sometimes a previous bad finished session can have visible = true
    FConnected := true;
  except
    try
      ExcelApplication.Disconnect;
      ExcelApplication.ConnectKind := ckNewInstance;
      ExcelApplication.Connect;
      ExcelApplication.EnableEvents := true;
      ExcelApplication.OnWorkbookOpen := OnAppWorkbookOpen;
      ExcelApplication.OnNewWorkbook := OnAppWorkbookNew;
      ExcelApplication.DisplayAlerts[FLCID] := true;
      ExcelApplication.AskToUpdateLinks[FLCID] := false;
      ExcelApplication.Visible[FLCID] := false; // sometimes a previous bad finished session can have visible = true
      FConnected := true;
    except
      raise EExcelOpen.Create(rcExcelOpenError);
    end;
  end;
end;


function TExcelServer.FindBuildinChartTypes: TStrings;

  function FileSearch(Path : String = '') : string;
  const
    Mask = 'Xl8galry.xls';
    StartFolder = '\Microsoft Office';
  var
    Rec : TSearchRec;
  begin
    Result := '';
    if Path = ''
    then
      Path := GetEnvironmentVariable('Programfiles') + StartFolder;

    if FindFirst(Path + '\' + Mask, faAnyFile - faDirectory, Rec) = 0
    then
    begin
      Result := Path + '\' + Rec.Name;
      SysUtils.FindClose(Rec);
      Exit;
    end
    else
    begin
      if FindFirst(Path + '\*.*', faDirectory, Rec) = 0
      then
      begin
        repeat
          if ((Rec.Attr and faDirectory) = faDirectory) and
             (Rec.Name[1] <> '.')
          then
              Result := FileSearch(Path + '\' + Rec.Name);
        until (FindNext(Rec) <> 0) or (Result <> '');
      end;
    end;
    SysUtils.FindClose(Rec);
  end;

// NUR Excel 2007
  function FileSearch_abVersion12(Path : String = '') : TStrings;
  const
    Mask = '*.crtx';
    StartFolder = '\Anwendungsdaten\Microsoft\Templates\Charts';
  var
    Rec : TSearchRec;
  begin
    Result := TStringList.Create;
    if Path = ''
    then
      Path := GetEnvironmentVariable('Userprofile') + StartFolder;

    if FindFirst(Path + '\' + Mask, faAnyFile - faDirectory, Rec) = 0
    then
    begin
      repeat
        Result.Add(ChangeFileExt(ExtractFileName(Rec.Name), ''));
      until (FindNext(Rec) <> 0);
    end
    else
    begin
      if FindFirst(Path + '\*.*', faDirectory, Rec) = 0
      then
      begin
        repeat
          if ((Rec.Attr and faDirectory) = faDirectory) and
             (Rec.Name[1] <> '.')
          then
            Result.AddStrings(FileSearch_abVersion12(Path + '\' + Rec.Name));
        until (FindNext(Rec) <> 0);
      end;
    end;
    SysUtils.FindClose(Rec);
  end;
// NUR Excel 2007

var
  i : integer;
  f : string;
  ExApp : TExcelApplication;
  WB : TExcelWorkbook;
  CH : TExcelChart;
begin
  Result := TStringList.Create;

  StartExcel(true);

  case Version.Major of
    0..11 : begin
              if not Assigned(CustomChartTypeList)
              then
              begin
                f := FileSearch;
                if f <> ''
                then
                begin
                  try
                    ExApp := TExcelApplication.Create(FOwner);
                    ExApp.ConnectKind := ckNewInstance;
                    ExApp.Connect;
                    try
                      ExApp.EnableEvents := true;
                    except
                      MessageDlg(rcExcelEnableEventsError, mtError, [mbOK], 0);
                      ExApp.EnableEvents := true;
                    end;
                    ExApp.DisplayAlerts[FLCID] := false;
                    ExApp.AskToUpdateLinks[FLCID] := false;
                    ExApp.Visible[FLCID] := false;
                    ExApp.OnWorkbookOpen := OnAppWorkbookOpen;
                    FbIsAppWbOpen := false;

                    ExApp.Workbooks.Open
                             (f,
                              EmptyParam{UpdateLinks}, EmptyParam{ReadOnly},
                              EmptyParam{Format}, EmptyParam{Password},
                              EmptyParam{WriteResPassword}, EmptyParam{IgnoreReadOnlyRecommended},
                              EmptyParam{Origin}, EmptyParam{Delimiter},
                              EmptyParam{Editable}, EmptyParam{Notify},
                              EmptyParam{Converter}, EmptyParam{AddToMru},
                              FLCID);

                    while not FbIsAppWbOpen do begin end; // auf Excel warten, bis Workbook offen ist

                    WB := TExcelWorkbook.Create(FOwner);
                    WB.ConnectTo(ExApp.ActiveWorkbook);

                    CH := TExcelChart.Create(FOwner);

                    for i := 1 to WB.Sheets.Count
                    do begin
                      CH.ConnectTo(WB.Sheets.Item[i] as _Chart);
                      Result.Add(CH.Name);
                    end;

                  finally
                    CH.Free;
                    WB.Free;
                    ExApp.Quit;
                    ExApp.Disconnect;
                  end;
                end;
                CustomChartTypeList := TStringList.Create;
                CustomChartTypeList.Assign(Result);
              end
              else
                Result.Assign(CustomChartTypeList);

            end;
   12 : begin
// ChartTemplate funktioniert bei Excel 2007 (noch) nicht
// Result.Assign(FileSearch_abVersion12);
            end;
  end;
  CloseExcel;
end;

procedure TExcelServer.PivotSet(Source, SheetName : string;
                       fromRowSource, fromColSource,
                       toRowSource, toColSource : integer;
                       fromRowDest : integer = 1; fromColDest : integer = 1);
begin
  // siehe: [url]http://support.microsoft.com/?scid=kb%3Ben-us%3B177169&x=13&y=13[/url]
  if Version.Major < 10 then
  begin
    PivotSet(Source, SheetName, fromRowSource, fromColSource, toRowSource, toColSource, fromRowDest, fromColDest, fromRowDest, fromColDest);
  end
  else
  begin
    try
      WorksheetAdd(SheetName);

      ExcelPivotTable := ExcelWorksheet.PivotTableWizard(xlDatabase{SourceType},
                     Source +
                     '!R' + IntToStr(fromRowSource) +
                     'C' + IntToStr(fromColSource) +
                     ':R' + IntToStr(toRowSource) +
                     'C' + IntToStr(toColSource){SourceData},
                     EmptyParam{TableDestination},
                     'PivotTable1'{TableName},
                     EmptyParam{RowGrand},
                     EmptyParam{ColumnGrand},
                     EmptyParam{SaveData},
                     EmptyParam{HasAutoFormat},
                     EmptyParam{AutoPage},
                     EmptyParam{Reserved},
                     EmptyParam{BackgroundQuery},
                     EmptyParam{OptimizeCache},
                     EmptyParam{PageFieldOrder},
                     EmptyParam{PageFieldWrapCount},
                     EmptyParam{ReadData},
                     EmptyParam{Connection},
                     FLCID);

      ExcelPivotTables := ExcelWorksheet.PivotTables(EmptyParam, FLCID) as PivotTables;

      ExcelPivotFields := ExcelPivotTable.PivotFields(EmptyParam) as PivotFields;

      if fromRowDest > 1
      then begin
        InsertRow(0, fromRowDest - 1);
      end;

      if fromColDest > 1
      then begin
        InsertColumn(0, fromColDest - 1);
      end;
    except
      raise EExcelPivotSet.Create(rcExcelPivotSetError);
    end;
  end;
end;

procedure TExcelServer.ChartSet(
  Source,
  SheetName : string;
  Charttype : TIvuExcelChartType;
  fromRowSource,
  fromColSource,
  toRowSource,
  toColSource : integer;
  fromPivot : boolean);
begin
  WorksheetConnect(Source);

  ExcelChart.ConnectTo(ExcelWorkbook.Charts.Add(EmptyParam, ExcelApplication.Sheets.Item[Source] as _WorkSheet, 1, EmptyParam, FLCID) as _Chart);
  ExcelChart.ChartType := GetChartType(Charttype);

  if fromPivot
  then begin
    try
      ExcelChart.ChartWizard(ExcelPivotTable.DataBodyRange);
    except
      on E : Exception do
        raise EExcelChartSetSourceData.Create(rcExcelChartSetError);
    end;
  end
  else begin
    try
      ExcelChart.ChartWizard(ExcelWorksheet.Range[TranslateCell(fromRowSource + 1, fromColSource + 1),
                                                    TranslateCell(toRowSource + 1, toColSource + 1)]);
    except
      on E : Exception do
        raise EExcelChartSetSourceData.Create(rcExcelChartSetError);
    end;
  end;

  ExcelChartObjects := (ExcelWorksheet.ChartObjects as ChartObjects);
  if ExcelChartObjects.Count > 0
  then
    ExcelChartObject := (ExcelChartObjects.Item(1) as ChartObject);

  try
    SetChartTitle(SheetName);
  except
    if Length(SheetName) = 31
    then
      SetLength(SheetName, 29);

    SheetName := SheetName + IntToStr(ExcelWorkbook.Worksheets.Count - 1);

    try
      SetChartTitle(SheetName);
    except
      on E : Exception do
        raise EExcelRenameWorksheet.Create(Format(rcExcelRenameSheetError, [ExcelWorksheet.Name, SheetName]));
    end;
  end;
end;
Erst seit Excel-Version 2007 wird eine Versionsabfrage notwendig, da hier die benutzerdefinieren Diagrammtypen ganz anders verwaltet werden.

Wie man sieht ist alle in einer Klasse gekapselt, aber mir schwebt eigentlich ein Server vor, der alle Excelklassen einzeln kapselt. Das ist allerdings eine Sisyphus-Arbeit weil dann jede Excel-Version unterschieden werden muss. Eine weitere Schwierigkeit ist der Umstand, das (fast) jedes Objekt eine Property auf alle (un)möglichen Objekte hat z.B.: Range("E10:G12").Application. Das macht in meinen Augen keinen Sinn.

Ich programmiere übrigens auch so, das ich in Excel den Makrorecorder anwerfe und dann in Delphi nachprogrammiere.

Ich hoffe ich konnte helfen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 10:00 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