如何从VBA中的Delphi com对象中的variant属性获取IDispatch信息?

时间:2009-12-21 17:43:36

标签: delphi vba com

我有一个用Delphi编写的COM对象,它有一个返回变量的属性。基本上这个属性返回一个值,具体取决于我传递的参数。当我从VBA(例如Excel)访问对象时,我可以编写如下内容:

MyObject.MyProperty("IntProperty") = 22

现在该属性还可以返回一个IDispatch对象,该对象存储在变体中。如果我从Delphi访问com对象,我编写以下代码来提取IDispatch信息

var
  Info : IMyInterface;

Info := IDispatch(TVarData(MyObject.MyProperty['InfoProperty']).VDispatch) as IMyInterface;

Info.foo := 10;
info.y   := 'test';
info.saveit;

是否可以在VBA中提取该IDispatch信息?我还没想出办法。

要100%清除,属性是OLEVariant类型,而不是IDispatch。我有IDispatch类型的属性,它们工作正常。

这是get_MethodProperty的声明

function get_MethodProperty(const aPropertyName: WideString):OLEVariant;

如果我将其声明为

,它会起作用
function get_MethodProperty(const aPropertyName: WideString):IDispatch;

但这不是我想要的。


这是VBA代码,它在第二行失败

Dim Info as Object
Set Info = MyObject.MethodProperty("InfoProperty")
Info.foo = 10
Info.y = "test"
call info.saveit

4 个答案:

答案 0 :(得分:0)

我不太确定你的意思是“提取IDispatch信息”。 VBA应该能够使用包含IDispatch的变体。简单的测试包括:

  1. 如果您从vba调用info.xxx,xxx是否会显示在您的GetIDsOfNames中?
  2. 如果从vba调用VarType(info),结果是vbObject吗? (== varDispatch)

答案 1 :(得分:0)

你可以像这样“提取”VBA中的IDispatch

Dim info As Object
Set info = MyObject.MyProperty("IntProperty")
info.foo = 10
info.y = "test"
info.saveit

答案 2 :(得分:0)

据我所知,如果涉及IDispatch,你使用的是后期绑定,因此我觉得像

Set info = CreateObject('WhatEverYourLibraryIs')

缺少 (也许这个关于Using early binding and late binding in Automation的微软链接也会有所帮助)

答案 3 :(得分:0)

我在我的一台自动化服务器上​​试过它,它在VBA(Excel)中运行良好。我在Delphi中的实现看起来像这样:

在主对象中获取方法:

function TApplication.Get_MethodProperty(const aPropertyName: WideString): OleVariant;
begin
  if aPropertyName = 'IntProperty' then begin
    result := 42;
  end else if aPropertyName = 'InfoProperty' then begin
    result := TInfoObject.Create as IDispatch;
  end;
end;

TInfoObject声明:

  TInfoObject = class(TAutoObject, IInfoObject)
  protected
    function Get_foo: Integer; safecall;
    procedure Set_foo(Value: Integer); safecall;
    function Get_y: WideString; safecall;
    procedure Set_y(const Value: WideString); safecall;
    procedure saveit; safecall;
  end;

TInfoObject实施:

{ TInfoObject }

function TInfoObject.Get_foo: Integer;
begin
  result := 123;
end;

function TInfoObject.Get_y: WideString;
begin
  result := 'info';
end;

procedure TInfoObject.Set_foo(Value: Integer);
begin
  // NYI
end;

procedure TInfoObject.Set_y(const Value: WideString);
begin
  // NYI
end;

procedure TInfoObject.saveit;
begin
  ShowMessage('saveit');
end;

VBA测试代码:

Dim Info As Object

Set Info = MyObject.MethodProperty("InfoProperty")

Info.foo = 10
Info.y = "test"

Call Info.saveit

如果这在你的应用中不起作用,请你提供你的VBA错误信息。

相关问题