【问题标题】:Can VBA enumerate a COM object's methods or fields?VBA 可以枚举 COM 对象的方法或字段吗?
【发布时间】:2011-11-09 01:33:31
【问题描述】:

我有一个在 VBA (Excel) 中使用的 COM 对象(用 C#.NET 构建),枚举 COM 对象的字段并自动引用它们会非常好。在 .NET 中,这可以通过反射来完成。有没有办法在 VBA 中做到这一点?

所以,而不是

Dim x As MyCOMObject
Set x = New MyCOMObject
x.f1 = 1
x.f2 = 2
x.f3 = 3

有点像:

Dim x As MyCOMObject
Set x = New MyCOMObject
For i = 0 to COMFieldCount(x) - 1
    SetCOMField(x, GetCOMFieldName(i), i+1)
Next i

【问题讨论】:

  • 我什至不会在 C# 中使用反射来执行此操作。你有没有想过做一个这样的功能?
  • @parapurarajkumar,您为什么不在 C# 中使用反射来执行此操作?我正在尝试创建一个执行此操作的函数,因此提出了问题。
  • @GTG,感谢您的链接——通过官方渠道很难找到 DLL,而且似乎与示例不完全匹配,但我认为这将是答案。
  • 不幸的是,@GTG 的链接对我不起作用。奇怪的是,VarType(x) 等于 vbString (8)。但这显然不是字符串;我可以显式访问它的字段和方法。 TLI.TypeInfoFromRecordVariant(x) 返回 Nothing。

标签: vba com field enumerate typelib


【解决方案1】:

您可能需要稍微改进此代码,但它大致可以满足您的需求。 首先,您需要添加对“Typelib 信息”的引用,TLBINF32.dll。我不确定这是 Windows 的一部分,还是我在机器上安装的众多 SDK 中的一些附带的,但它位于 System32 文件夹中。

我假设您正在设置 COM 对象的属性,因此您将调用“property put”函数来设置对象的值。您可能需要检查这些属性的数据类型,我的代码中没有进行任何数据类型转换。

代码如下所示:

'Define the variables
Dim tliApp As TLI.TLIApplication
Dim typeinfo As TLI.typeinfo
Dim interface As TLI.InterfaceInfo
Dim member As TLI.MemberInfo

'Initialize typelib reflector
Set tliApp = New TLI.TLIApplication
'Get the type information about myObject (the COM object you want to process)
Set typeinfo = tliApp.ClassInfoFromObject(myObject)

'Set all properties of all the object's interfaces
For Each interface In typeinfo.Interfaces
    For Each member In interface.Members
        'If this is a "property put" function
        If member.InvokeKind = INVOKE_PROPERTYPUT Then
            'Invoke the mebmer and set someValue to it.
            'Note that you'll probably want to check what datatype to use and do some more error checking
            CallByName myObject, member.Name, VbLet, someValue
        End If
    Next
Next

【讨论】:

  • CallByName 是一个我不知道的非常有用的例程。但是,枚举不适用于我的对象,因为识别的接口只是 IDispatch(QueryInterface、AddRef 等)和一些额外的。 ClassInfoFromObject 在我的对象上检索到的两个接口是_MyObjectType 和_Object。第一个只是一个 IDispatch 接口。第二个还包含成员 ToString、Equals、GetHashCode 和 GetType。此外,我想设置字段而不是属性;例如,在我的 C# 模块中,我声明了 public double aDoubleField;
猜你喜欢
  • 2011-11-16
  • 2011-01-07
  • 2014-09-20
  • 2013-09-02
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
相关资源
最近更新 更多