Search code examples
delphivariantoffice-automation

How to test if a OleVariant contains an interface


One of the annoying things with working with Excel through its automation interface is the weak typing.
A return value can contain anything different types.
How do I test if the variant returned by caller is an ExcelRange interface?

function TAddInModule.InBank: boolean;
var
  ExcelAppAsVariant: OleVariant;
  test: string;
  Caller: OleVariant;
begin  //Exception handling omitted for brevity. 
  Result:= false;
  ExcelAppAsVariant:= ExcelApp.Application;
  Caller:= ExcelApp.Application.Caller[EmptyParam, 0];
  if IDispatch(Caller) is ExcelRange then begin //E2015 Operator not applicable 
    Result:= lowercase(Caller.Parent.Name) = 'bank' 
  end;
end;

(Strangly enough the as operator works (IDispatch(Caller) as ExcelRange).Parent; compiles just fine).

The following code works, but seems overly verbose:

if VarIsType(Caller, varDispatch) then begin 
  IUnknown(Caller).QueryInterface(ExcelRange, ICaller) 
  if Assigned(ICaller) then ICaller......

There is also no built-in function VarIsInterface(Variant, Interface).
How do I test that an OleVariant contains a given interface?

See also: How to cast OleVariant to IDispatch derived?

EDIT
Thanks all, I used the following to do the testing, because Excel mixes interfaces and OleStrings as possible return values.

if VarIsType(Caller, varDispatch) and Supports(Caller, ExcelRange) then begin

Solution

  • I'd probably use Supports for this:

    if Supports(Caller, ExcelRange) then
      ....
    

    This resolves to the same code as given by @Stijn but the Supports call is rather more concise.