我开发了一个VB.NET库(部分是在C#上开发的),它很大程度上依赖于从抽象通用基类继承而来,并且我试图找出最佳实践。我不得不使用框架3.5来做到这一点。
Public MustInherit Class MyBaseClass(Of T)
Public Whatever As T
End Class
Public Class MyDerivedClass
Inherits MyBaseClass(Of String)
Private _myProperty As String
Public Property MyProperty As String
Get
Return _myProperty
End Get
Set(value As String)
_myProperty = value
End Set
End Property
End Class
我将.tlb文件作为VBA中的引用附加(使用Excel),然后运行以下代码:
Dim m As New VBtoVBA.MyDerivedClass
m.MyProperty = "foo"
我收到错误"运行时错误430:类不支持自动化或不支持预期的接口"。
另一方面,我将第一行更改为:
Public MustInherit Class MyBaseClass
Public Whatever As String
End Class
Public Class MyDerivedClass
Inherits MyBaseClass
VBA脚本有效。因此,我认为问题在于泛型(也在其他来源中有记录)。但是,删除我的库的通用功能是不可能的。最好的"我能想到的解决方法是编写一个包含MyDerivedClass作为字段的第三个类,并作为非泛型接口使用它:
Public Class MyDerivedClassString
Private _innerObj As New MyDerivedClass
Public Property MyProperty As String
Get
Return _innerObj.MyProperty
End Get
Set(value As String)
_innerObj.MyProperty = value
End Set
End Property
Public Property Whatever As String
Get
Return _innerObj.Whatever
End Get
Set(value As String)
_innerObj.Whatever = value
End Set
End Property
End Class
通过这种方式,我可以像在VBA中一样使用它:
m.Whatever = "wha"
MsgBox (m.Whatever)
顺便说一下,我认为可能有另一种(更好的)方法来实现相同的结果,我真的希望如此,因为m库是由几十个类组成的。
非常感谢。
答案 0 :(得分:6)
正如我在评论中提到的,为MS Office应用程序编写库(dll)有点......硬编码。此dll必须公开方法和属性才能在COM自动化中使用它。为了能够实现这一点,您需要编写接口:
Namespace VBtoVBA
Public Interface IMyDerivedClass
Property MyProperty As String
End Interface
End Namespace
然后在DerivedClass
Public Class MyDerivedClass
Inherits MyBaseClass(Of String)
Implements IMyDerivedClass
Private _myProperty As String
Public Property MyProperty As String Implements IMyDerivedClass.MyProperty
现在,转到Project Properties
窗口
1)选择Application
标签 - 点击Assembly Information
按钮,然后在下一个窗口中选择Make assembly COM visible
复选框(使用OK
按钮应用设置),
2)选择Compile
标签 - 选择Register for COM interop
复选框
3)保存项目并构建dll
4)现在,转到Office应用程序中的VBA代码编辑器 - > References
菜单。在Reference window
添加对yourDllName.tlb
现在,您可以在Office应用程序中使用您的dll;)
我测试了代码:
Option Explicit
Sub DoSomething()
Dim m As VBtoVBA.MyDerivedClass
Set m = New VBtoVBA.MyDerivedClass
m.MyProperty = "Something"
MsgBox m.MyProperty
End Sub
它也有效;)