Einzelnen Beitrag anzeigen

peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
701 Beiträge
 
Delphi 12 Athens
 
#6

AW: EXCEL-Befehle anwenden

  Alt 6. Mai 2022, 13:03
Excel ist ein OLE Automation Server und Delphi unterstützt OLE Automation seit Delphi 1. Die einfachste Methode ist late binding über Variants, die Support für IDispatch quasi eingebaut haben. Das sieht etwa so aus:
Delphi-Quellcode:
var
  Excel, WB: OLEVariant;
  LCount: Integer;
  LName: string;
  LPath: string;
begin
  Excel := CreateOleObject('Excel.Application');
  try
    LPath := TPath.Combine(TPath.GetDocumentsPath, 'sflib.xlsx');
    Excel.Workbooks.Open(LPath);
    WB := Excel.Workbooks.Item[1];
    WB.Activate;
    LName := WB.Name;
    LCount := WB.Sheets.Count;
    ShowMessage(Format('The workbook %s has %d sheets.',
      [LName, LCount]));
    WB.Close;
  finally
    Excel.Quit;
  end;
Die notwendigen Units in der Uses-Klausel sind System.Win.ComObj und (für TPath) System.IOUtils.
Diese Art von OLE Automation ist von der Syntax her der von VBA sehr ähnlich, aber es gibt einen massiven Nachteil:
Der Compiler "kennt" den verwendeten Automation Server nicht und kann daher den Kode nicht prüfen, etwaige Fehler werden erst zur Laufzeit angezeigt. Und Code completion geht auch nicht, man muss sich also quasi blind anhand der Excel-VBA Dokumentation durchschlagen.

Die Alternative ist early binding, die Verwendung von in der type library definierten interfaces des Servers. Dafür braucht man eine durch Import der type library erstellte Unit. Delphi liefert eine mit, drei Versionen sogar, die neueste ist Excel2010.pas.

Damit sieht der Kode in etwa so aus:

Delphi-Quellcode:
var
  Excel: ExcelApplication;
  WB: ExcelWorkbook;
  LCount: Integer;
  LName: string;
  LPath: string;
begin
  Excel := CreateOleObject('Excel.Application') as ExcelApplication;
  try
    LPath := TPath.Combine(TPath.GetDocumentsPath, 'sflib.xlsx');
    Excel.Workbooks.Open(LPath, false, false, Unassigned,Unassigned,
      Unassigned,Unassigned,Unassigned,Unassigned,Unassigned,Unassigned,
      Unassigned,Unassigned,Unassigned,Unassigned, 1031);
    WB := Excel.Workbooks.Item[1];
    WB.Activate(1031);
    LName := WB.Name;
    LCount := WB.Sheets.Count;
    ShowMessage(Format('The workbook %s has %d sheets.',
      [LName, LCount]));
    WB.Close(false, Unassigned, Unassigned, 1031);
  finally
    Excel.Quit;
  end;
Code completion funktioniert, aber leider hat auch das seinen Preis: man muss immer für alle Parameter einer Funktion einen Wert angeben, auch für die optionalen. "Unassigned" ist ein "leerer" OleVariant, den die Unit System.Variants zur Verfügung stellt.

Man kann beide Methoden auch mischen...
Peter Below
  Mit Zitat antworten Zitat