2011-01-26 14 views
6

Tengo un módulo de clase personalizado en VBA (Access) que se supone maneja una gran cantidad de datos externos. Actualmente tengo dos funciones Read(name) y Write(name, value) que permiten leer y establecer propiedades dinámicas.Nombres de propiedades dinámicas en VBA

¿Hay alguna manera de definir una forma más sintáctica de leer y escribir esos datos? Sé que algunos objetos en VBA tienen una forma especial de acceder a los datos, por ejemplo, el RecordSet, que permite leer y establecer datos usando myRS!property_name. ¿Hay alguna manera de hacer exactamente lo mismo para los módulos de clase personalizados?

Respuesta

4

bien, gracias a Alain y KyleNZ Ahora he encontrado una manera de trabajar para hacer esto, sin tener una colección o un objeto enumerable a continuación.

Básicamente, gracias al nombre de la! operador, descubrí, que el acceso a través del operador bang/pling es equivalente a acceder al miembro predeterminado de un objeto. Si la propiedad Value es el miembro predeterminado de mi módulo de clase, entonces hay tres declaraciones equivalentes de acceso a esa propiedad:

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

Así que para hacer un corto sintaxis de trabajo para un módulo de clase personalizada, todo lo que uno tiene que hacer es para definir un miembro predeterminadoPor ejemplo, ahora he utilizado la Value propiedad siguiente:

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 

Normalmente, se puede acceder ahora a que de esta manera:

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

Ahora para hacer que la propiedad del miembro predeterminado, hay que añadir una línea a la definición de la propiedad:

Attribute Value.VB_UserMemId = 0 

Así, termino con esto:

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 

Y después de eso, esto funciona y equivalente a la palabra clave:

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] 

Tenga en cuenta que hay que añadir la Attribute Value.VB_UserMemId = 0 en algún otro editor que el editor de VBA que se incluye con Microsoft Office, como que uno oculta las directivas Attribute por algún motivo. Puede exportar fácilmente el módulo, abrirlo en el bloc de notas, agregar las directivas e importarlo de nuevo en el editor de VBA. Siempre y cuando no cambie demasiado con el miembro predeterminado, la directiva no se debe eliminar (solo asegúrese de comprobarlo de vez en cuando en un editor externo).

2

Ver esta otra pregunta: Bang Notation and Dot Notation in VBA and MS-Access

El operador bang es la abreviatura de miembros el acceso de una colección o de otros objeto enumerable

Si usted hace su clase extender la Colección (!) clase en VBA, entonces debería poder aprovechar esos operadores. En la siguiente pregunta es un ejemplo de un usuario que extendió la clase de colección: Extend Collections Class VBA

6

La sintaxis de signo de exclamación se utiliza para acceder a los miembros de una instancia Scripting.Dictionary (que tendrá que añadir una referencia a Microsoft Scripting Runtime través de Herramientas> Referencias primero). Para utilizar esta sintaxis, deberá almacenar la información internamente en un diccionario.

La forma más rápida para utilizarlo en una clase es dar su clase de una variable de objeto de tipo Scripting.Dictionary y configurarlo de la siguiente manera:

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 

Ahora se puede acceder a las propiedades utilizando myinstance.IntData!MyProperty = 1 ... pero a Llegue al lugar donde desea estar. Necesita usar Charlie Pearson's technique para hacer que IntData sea el miembro predeterminado de su clase.

Una vez hecho esto, puede utilizar la siguiente sintaxis:

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 
+0

Bien, gracias hasta ahora ... ¿pero hay alguna forma de usar esto sin tener un Dictionary/Collection subyacente? Mis datos provienen de un archivo XML y la clave de índice que quiero usar se basa parcialmente en la ruta. – poke

+0

Si su biblioteca XML expone el contenido de los nodos relevantes como un diccionario, podría definir una propiedad que devuelva ese diccionario y convertir esa propiedad en el miembro predeterminado; si es un poco más complicado, podrías intentar crear propiedades de mapeo del diccionario para el XPath a instancias particulares. Esta técnica se basa bastante en un diccionario o colección. – KyleNZ

Cuestiones relacionadas