2011-04-10 9 views
12

Si se devuelven matrices por referencia, ¿por qué no los siguientes trabajos:VBA - Volviendo matriz a partir de Property Get

'Class1 class module 
Private v() As Double 
Public Property Get Vec() As Double() 
    Vec = v() 
End Property 
Private Sub Class_Initialize() 
    ReDim v(0 To 3) 
End Sub 
' end class module 

Sub Test1() 
    Dim c As Class1 
    Set c = New Class1 
    Debug.Print c.Vec()(1) ' prints 0 as expected 
    c.Vec()(1) = 5.6 
    Debug.Print c.Vec()(1) ' still prints 0 
End Sub 

Respuesta

10

En VBA, las matrices son nunca regresaron por referencia a menos que se devuelven a través de un parámetro ByRef. Además, cada vez que utiliza = para asignar una matriz a una variable, ha creado una nueva copia de la matriz, incluso si la está asignando a un argumento ByRef dentro de un procedimiento, por lo que no tiene suerte. tratando de hacer que esto funcione

Algunas alternativas son ...

  • Utilice un VBA.Collection lugar de una matriz.
  • Crea tu propia clase que encapsula una matriz y expone los procedimientos para acceder indirectamente y manipular la matriz interna.
+0

Creo que esto es perfecto. Empareja lo que he observado. Aunque me gustaría que estas cosas estuvieran mejor documentadas. ¿Tiene una buena fuente (más allá de la experiencia) donde se explican cosas como esta? – jtolle

+0

Chip Person, un consultor de Excel y MVP, dice en su sitio que "las matrices siempre se pasan por referencia" http://www.cpearson.com/excel/byrefbyval.aspx ¿Está equivocado? – ThomasMcLeod

+0

Su sitio es ciertamente bueno. Quise decir más fuentes "oficiales", es decir, la ayuda, los viejos manuales de MS para VB, etc. Me vuelve loco que cosas básicas como "asignación con' = 'copias de arreglos" se dejen para que los MVP proporcionen, o para los usuarios descubrir a través de la experimentación. – jtolle

23

No tiene una propiedad de alquiler. Además, la propiedad get devuelve todo el conjunto, en lugar de solo el elemento en cuestión. Cambie el tipo de devolución de Property Get from Double() a simplemente Double. Agregar propiedad Let. Tenga en cuenta que se necesitan dos entradas, pero solo se le pasa uno. Se supone que la última variable (MyValue, en este caso) obtiene su valor de lo que sea después del signo =. Ponga un punto de corte en algún lugar temprano en Test1() y vea cómo los valores se ven afectados en la ventana Locales. Compare las variables creadas por el código original con mi código:

'Class1 class module 
Private v() As Double 
Public Property Get Vec(index As Long) As Double 
    Vec = v(index) 
End Property 
Public Property Let Vec(index As Long, MyValue As Double) 
    v(index) = MyValue 
End Property 
Private Sub Class_Initialize() 
    ReDim v(0 To 3) 
End Sub 
' end class module 

'Begin module 
Sub Test1() 
    Dim c As Class1 
    Set c = New Class1 
    Debug.Print c.Vec(1) ' prints 0 as expected 
    c.Vec(1) = 5.6 
    Debug.Print c.Vec(1) ' prints 5.6 
End Sub 
'End module 
+2

Esta es una respuesta mucho más útil que la aceptada. Gracias :) –

Cuestiones relacionadas