How to check if OleVariant contains an interface

One of the frustrating things when working with Excel through the automation interface is weak typing.
The return value can contain anything for different types.
How can I check if a variant returned by an caller

interface is ExcelRange

?

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;

      

(Oddly enough, the operator as

works and (IDispatch(Caller) as ExcelRange).Parent;

compiles just fine).

The following code works, but looks too 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 can I check that the OleVariant contains a given interface?

See also: How to distinguish OleVariant from IDispatch?

EDIT
Thanks everyone, 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

      

+3


source to share


3 answers


I would use Supports

for this:

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

      



This resolves the same code as @Stijn, but the call Supports

is more concise.

+3


source


The code is really, unfortunately, verbose, but close to what I usually use:



if IUnknown(Caller).QueryInterface(ExcelRange, ICaller)=S_OK then

      

+2


source


The module System.Variants

has functions VarSupports()

to test / extract the interface from (Ole)Variant

:

function VarSupports(const V: Variant; const IID: TGUID; out Intf): Boolean; overload;
function VarSupports(const V: Variant; const IID: TGUID): Boolean; overload;

      

For example:

Caller := ExcelApp.Application.Caller[EmptyParam, 0];
if VarSupports(Caller, ExcelRange) then
  Result := LowerCase(Caller.Parent.Name) = 'bank';

      

if VarSupports(Caller, ExcelRange, ICaller) then 
  ICaller.DoSomething;

      

+2


source







All Articles