通过其自动化界面使用Excel的一个令人讨厌的事情是打字很弱
返回值可以包含任何不同的类型
如何测试caller
返回的变体是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;
(as
运算符工作(IDispatch(Caller) as ExcelRange).Parent;
编译得足够好。
以下代码有效,但似乎过于冗长:
if VarIsType(Caller, varDispatch) then begin
IUnknown(Caller).QueryInterface(ExcelRange, ICaller)
if Assigned(ICaller) then ICaller......
也没有内置功能VarIsInterface(Variant, Interface)
如何测试OleVariant是否包含给定的界面?
另请参阅:How to cast OleVariant to IDispatch derived?
修改
谢谢大家,我使用以下方法进行测试,因为Excel将接口和OleStrings混合为可能的返回值。
if VarIsType(Caller, varDispatch) and Supports(Caller, ExcelRange) then begin
答案 0 :(得分:3)
答案 1 :(得分:2)
代码确实令人遗憾,冗长,但接近我通常使用的代码:
if IUnknown(Caller).QueryInterface(ExcelRange, ICaller)=S_OK then
答案 2 :(得分:2)
System.Variants
单元具有VarSupports()
个功能,用于从(Ole)Variant
测试/提取接口:
function VarSupports(const V: Variant; const IID: TGUID; out Intf): Boolean; overload;
function VarSupports(const V: Variant; const IID: TGUID): Boolean; overload;
例如:
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;