12

I need to test if I can use Excel OLE from my program since it can be launched on PCs without Excel. Code samples on the net assume Excel is installed, but what if not?

XLApp := CreateOleObject('Excel.Application');
try
  // Hide Excel
  XLApp.Visible := False;
  // Open the Workbook
  XLApp.Workbooks.Open(aPath);
  ...snip...
finally
  // Quit Excel
  if not VarIsEmpty(XLApp) then
  begin
    XLApp.Quit;
    XLAPP := Unassigned;
  end;
end;

Would that be correct code to find if Excel is installed?

//Try to create Excel OLE
try
  XLApp := CreateOleObject('Excel.Application');
except
  ShowMessage('Error opening Excel');
  Exit;
end;
Kromster
  • 7,181
  • 7
  • 63
  • 111

1 Answers1

17

You can use a code based on the Scalabium's tip to check whether Excel is available. Or something like:

uses ComObj, ActiveX;

function IsObjectAvailable(const ClassName: string): Boolean;
var
  ClassID: TCLSID;
begin
  Result := Succeeded(CLSIDFromProgID(PWideChar(WideString(ClassName)), 
    ClassID));
end;

You can also check if Excel is running by using following code:

function IsObjectActive(const ClassName: string): Boolean;
var
  ClassID: TCLSID;
  Unknown: IUnknown;
begin
  Result := False;
  if Succeeded(CLSIDFromProgID(PWideChar(WideString(ClassName)), ClassID)) then
    Result := Succeeded(GetActiveObject(ClassID, nil, Unknown));
end;

And then in some procedure or event:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if IsObjectAvailable('Excel.Application') then 
    ShowMessage('Excel is available');
  if IsObjectActive('Excel.Application') then 
    ShowMessage('Excel is running');
end;
TLama
  • 75,147
  • 17
  • 214
  • 392
Guillem Vicens
  • 3,936
  • 30
  • 44
  • 7
    +1 But I would continue to use `try CreateOleObject except` in my application, because I believe it's the only reliable way to make sure I can actually *create* an object instance (via `CoCreateInstance`). The method above could be used as a preliminary test to check that the class is correctly registered. – kobik Feb 22 '13 at 11:55
  • @kobik, I agree. In my answer I assumed OP only needed to know how to check for Excel being installed, and that the `try CreateOleObject` would be used for the object instance creation part anyway. – Guillem Vicens Feb 22 '13 at 12:28
  • 1
    @Guilem, `CreateOleObject` will also be doing `OleCheck(CLSIDFromProgID...` (`ProgIDToClassID`) anyway. So I don't really see the point in doing it again in the first place, if you intend to `try CreateOleObject` in any case... – kobik Feb 22 '13 at 12:33
  • 1
    @kobik, imho it depends. They do not necessarily need to be coupled. For example, you might just want to check if Excel is installed to enable or disable some option in your app. Then, if it was enabled, use `CreateOleObject` where necessary. Granted, this does not seem to be the case of the OP. – Guillem Vicens Feb 22 '13 at 12:43
  • 2
    @kobik, I'd use this e.g. at some application startup check if an instance of the OLE object would not be actually needed (yet), or might not be needed at all during application runtime (e.g. to build some special menu just when the OLE object would be available). – TLama Feb 22 '13 at 12:48