Динамические имена свойств в VBA - PullRequest
7 голосов
/ 26 января 2011

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

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

Ответы [ 3 ]

7 голосов
/ 26 января 2011

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

Самый быстрый способ использовать ее в классе - это дать вашему классу объектную переменную типа 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
6 голосов
/ 27 января 2011

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

3 голосов
/ 26 января 2011

См. Этот другой вопрос: Нотация взрыва и Нотация точек в VBA и MS-Access

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...