pok*_*oke 7 vba properties class
我在VBA(Access)中有一个自定义类模块,它应该处理大量的外部数据.目前我有两个功能Read(name)
,并Write(name, value)
允许读取和设置动态特性.
有没有办法定义更多的语法方式来读取和写入这些数据?我知道VBA中的某些对象有一种特殊的访问数据的方式,例如RecordSet
,它允许使用读取和设置数据myRS!property_name
.有没有办法对自定义类模块做同样的事情?
小智 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
Run Code Online (Sandbox Code Playgroud)
现在您可以使用myinstance.IntData!MyProperty = 1
... 来访问属性了,但是为了达到您想要的位置,您需要使用Charlie Pearson的技术来IntData
为您的类创建默认成员.
完成后,您可以使用以下语法:
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
Run Code Online (Sandbox Code Playgroud)
好的,感谢Alain和KyleNZ,我现在找到了一种方法来做到这一点,下面没有一个集合或可枚举的对象.
基本上,多亏了这个名字!运算符,我发现,通过bang/pling运算符访问等同于访问对象的默认成员.如果属性Value
是我的类模块的默认成员,则有三个等效语句来访问该属性:
obj.Value("param")
obj("param")
obj!param
Run Code Online (Sandbox Code Playgroud)
因此,要为自定义类模块制作一个简短的语法,所有人必须做的就是定义一个默认成员.例如,我现在使用以下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
Run Code Online (Sandbox Code Playgroud)
通常,您现在可以像这样访问:
obj.Value("foo") = "New value"
MsgBox obj.Value("foo")
Run Code Online (Sandbox Code Playgroud)
现在要将该属性设为默认成员,您必须在属性定义中添加一行:
Attribute Value.VB_UserMemId = 0
Run Code Online (Sandbox Code Playgroud)
所以,我最终得到了这个:
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
Run Code Online (Sandbox Code Playgroud)
在那之后,这工作并且相当于上面显示的代码:
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]
Run Code Online (Sandbox Code Playgroud)
请注意,您必须添加Attribute Value.VB_UserMemId = 0
除Microsoft Office附带的VBA编辑器之外的其他编辑器,因为Attribute
出于某种原因隐藏了指令.您可以轻松导出模块,在记事本中打开它,添加指令并导入它回到VBA编辑器.只要您不使用默认成员进行太多更改,就不应删除该指令(只需确保在外部编辑器中不时检查).