VBA中的动态属性名称

时间:2011-01-26 13:13:04

标签: class vba properties

我在VBA(Access)中有一个自定义类模块,它应该处理大量的外部数据。目前,我有两个函数Read(name)Write(name, value),可以读取和设置动态属性。

有没有办法定义更多语法来读取和写入这些数据?我知道VBA中的某些对象有一种特殊的访问数据的方式,例如RecordSet,它允许使用myRS!property_name读取和设置数据。有没有办法对自定义类模块做同样的事情?

3 个答案:

答案 0 :(得分:7)

感叹号语法用于访问Scripting.Dictionary个实例的成员(您需要先通过工具>引用添加对Microsoft Scripting Runtime的引用)。要使用此syntaxy,您需要将信息内部存储在字典中。

在类中使用它的最快方法是为类提供类型为Scripting.Dictionary的对象变量,并按如下所示进行设置:

Option Explicit

Dim d As Scripting.Dictionary

Private Sub Class_Initialize()
    Set d = New Scripting.Dictionary
End Sub

Private Sub Class_Terminate()
    Set d = Nothing
End Sub

Public Property Get IntData() As Scripting.Dictionary
    Set IntData = d
End Property

现在,您可以使用myinstance.IntData!MyProperty = 1访问媒体资源了...但是为了达到您想要的目标,您需要使用Charlie Pearson's technique使IntData成为您班级的默认成员。< / p>

完成后,您可以使用以下语法:

Dim m As MyClass
Set m = New MyClass

Debug.Print "Age = " & m!Age ' prints: Age = 
m!Age = 27
Debug.Print "Age = " & m!Age ' prints: Age = 27
Set m = Nothing

答案 1 :(得分:6)

好的,感谢Alain和KyleNZ,我现在找到了一种方法来做到这一点,下面没有收集或可枚举的对象。

基本上,多亏了名字!运算符,我发现,通过bang / pling运算符访问等同于访问对象的默认成员。如果属性Value是我的类模块的默认成员,那么有三个等效语句来访问该属性:

obj.Value("param")
obj("param")
obj!param

因此,要为自定义类模块制作一个简短的语法,所有人必须做的就是定义一个默认成员。例如,我现在使用以下Value属性:

Property Get Value(name As String) As String
    Value = SomeLookupInMyXMLDocument(name)
End Property

Property Let Value(name As String, val As String) As String
    SetSomeNodeValueInMyXMLDocument(name, val)
End Property

通常,您现在可以像这样访问:

obj.Value("foo") = "New value"
MsgBox obj.Value("foo")

现在要将该属性设为默认成员,您必须在属性定义中添加一行:

Attribute Value.VB_UserMemId = 0

所以,我最终得到了这个:

Property Get Value(name As String) As String
Attribute Value.VB_UserMemId = 0
    Value = SomeLookupInMyXMLDocument(name)
End Property

Property Let Value(name As String, val As String) As String
Attribute Value.VB_UserMemId = 0
    SetSomeNodeValueInMyXMLDocument(name, val)
End Property

之后,这与上面显示的代码相同:

obj("foo") = "New value"
MsgBox obj("foo")

' As well as
obj!foo = "New value"
MsgBox obj!foo

' Or for more complex `name` entries (i.e. with invalid identifier symbols)
obj![foo] = "New value"
MsgBox obj![foo]

请注意,您必须在除Microsoft Office附带的VBA编辑器之外的其他编辑器中添加Attribute Value.VB_UserMemId = 0,因为出于某种原因,它会隐藏Attribute指令。您可以轻松导出模块,在记事本中打开它,添加指令,然后在VBA编辑器中将其导入。只要您不使用默认成员进行太多更改,就不应删除该指令(只需确保在外部编辑器中不时进行检查)。

答案 2 :(得分:3)

请参阅另一个问题:Bang Notation and Dot Notation in VBA and MS-Access

  

爆炸操作员(!)是简写   访问集合的成员或   其他可枚举对象

如果你让你的类在VBA中扩展Collection类,那么你应该能够利用这些运算符。在下面的问题是扩展集合类的用户的示例: Extend Collections Class VBA