Динамические имена свойств в VBA

у меня есть пользовательский модуль класса в VBA (Access), который должен обрабатывать большой объем внешних данных. В настоящее время у меня есть две функции Read(name) и Write(name, value) что позволяет читать и устанавливать динамические свойства.

есть ли способ определить более синтаксический способ чтения и записи этих данных? Я знаю, что некоторые объекты в VBA есть специальный способ доступа к данным, например,RecordSet, который позволяет читать и записывать данные с помощью myRS!property_name. Есть ли способ сделать то же самое для пользовательские модули класса?

3 ответов


синтаксис восклицательного знака используется для доступа к членам Scripting.Dictionary экземпляр (вам нужно добавить ссылку на Microsoft Scripting Runtime инструменты > ссылок). Для использования этого syntaxyou потребуется для хранения информации внутри словаря.

самый быстрый способ использовать его в классе-дать вашему классу объектную переменную типа 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... но чтобы попасть туда, куда вы хотите вам нужно использовать техника Чарли Пирсона для изготовления 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

хорошо, благодаря Алену и 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]

обратите внимание, что вы должны добавить Attribute Value.VB_UserMemId = 0 в каком-то другом редакторе, кроме редактора VBA, который поставляется с Microsoft Office, так как он скрывает Attribute директивы по какой-то причине.. Вы можете легко экспортировать модуль, открыть его в блокноте, добавить директивы и импортировать его обратно в Редактор VBA. Пока вы не слишком сильно меняетесь с членом по умолчанию, директива не должна быть удалена (просто убедитесь, что вы проверяете время от времени во внешнем редактор.)


этот другой вопрос: обозначения взрыва и точечные обозначения в VBA и MS-Access

оператор бац (!) стенография для доступ к членам коллекции или другой перечисляемый объект

Если вы сделаете свой класс расширяющим класс коллекции в VBA, вы сможете воспользоваться этими операторами. В следующем вопросе приведен пример пользователя, который расширил класс collection: Расширить Класс Коллекций VBA