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
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.