Динамические имена свойств в 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