2
votes

I use Windows 10, Delphi Berlin and Microsoft Office 2007. I try to get the number of opened Excel window. When I download Excel file and open it a seperated Excel runs so only one workbook exists in one Excel window.

I imported Microsoft Office 12.0 Object Library and wrote 2 procedures. Button1Click works with tExcelApplication and Button2Click does with CreateOleObject('excel.application'). After I run Excel the former works well but Count is recognized as an error just in the editor and the latter returns 0.

How Can I remove the annoying error message or get the _Excel to work?

type
  TForm1 = class(TForm)
    ExcelApplication1: TExcelApplication;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Caption := IntToStr(ExcelApplication1.Windows.Count);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  _Excel: Variant;
begin
  _Excel := CreateOleObject('excel.application');

  Button2.Caption := _Excel.windows.count;
end;

enter image description here

1

1 Answers

3
votes

The message in the IDE is because you are using late bound COM. The method calls are dispatched at runtime and only at runtime do you find out whether or not the method exists. Because of that the compiler can't check the validity of your code. Your code is fine because it executes correctly, but the nature of late bound COM means the IDE thinks your code contains syntax errors. You just have to ignore it when using late bound COM.

You can switch instead to early bound COM and have the compiler be able to check the syntax of your code.

There are pros and cons of both approaches. Late bound can often yield simpler and more concise code. But at the expense of frustration when you only find out your mistakes at runtime.

If the value returned is zero then I guess the obvious conclusion is that there are no windows. The late bound code is creating a new instance of Excel, but the early bound code is attaching to an existing instance. To obtain an existing instance, if there is one, use GetActiveOleObject.