tags:

views:

33

answers:

1

I think I have a pretty good handle on how to handle module level arrays in VBA though Property Get and Let. Is there a way to ReDim a module level array through a property?

The following code errors out at the ReDim statement in the last procedure (DoTest).

Private mstrTestArray() As String

Private Sub Class_Initialize()
    ReDim mstrTestArray(0) As String
End Sub

Private Property Get TestArray() As String()
    TestArray = mstrTestArray
End Property

Private Property Let TestArray(ByRef strTestArray() As String)
    mstrTestArray = strTestArray
End Property

Private Property Get TestArrayValue(d1 As Long) As String
    TestArrayValue = mstrTestArray(d1)
End Property

Private Property Let TestArrayValue(d1 As Long, strValue As String)
    mstrTestArray(d1) = strValue
End Property

Sub DoTest()
    Dim intCharCode As Integer
    For intCharCode = 97 To 122
        If Not Len(TestArrayValue(UBound(TestArray))) > 0 Then
            TestArrayValue(UBound(TestArray)) = Chr(intCharCode)
        Else
            ReDim Preserve TestArray(UBound(TestArray) + 1) As String
            TestArrayValue(UBound(TestArray)) = Chr(intCharCode)
        End If
    Next intCharCode
    Debug.Print TestArrayValue(LBound(TestArray)) _
    & " through " _
    & TestArrayValue(UBound(TestArray))
End Sub

Thanks!

+2  A: 

This is a good question. I'll answer your question directly at the bottom, but let's start with a brief background of Object-Oriented Programming in VBA. In most object-oriented languages, a property will often look like a field, but act like a method. What does this mean?

When you instantiate a class and set a value to a property, it looks like this:

Sub TestMyClass()
    Dim mc As MyClass
    Set mc = new MyClass
    mc.MyProperty = 1
End Sub

In the above code, MyProperty looks like a field, right? But let's look at how it's defined in the class:

Private pMyProperty As Integer

Public Property Get MyProperty() As Integer
    MyProperty = pMyProperty
End Property

Public Property Let MyProperty(lMyProperty As Integer)
    pMyProperty = lMyProperty
End Property

As you can see in the above code, while pMyProperty is an Integer field, the public Get and Set methods for MyProperty actually look more like methods. A property "wraps" around a field and is especially helpful in setting access to the underlying field.

In your example, you were trying to ReDim a property that returns a reference to the array. I'm not 100% sure, but I don't think you can use ReDim on a reference of an array.

I changed your code to modify the actual Private field mstrTestArray and it seemed to work fine. Is that something you can try?

Sub DoTest()
    Dim intCharCode As Integer
    For intCharCode = 97 To 122
        If Not Len(TestArrayValue(UBound(TestArray))) > 0 Then
            TestArrayValue(UBound(TestArray)) = Chr(intCharCode)
        Else
            ReDim Preserve mstrTestArray(UBound(mstrTestArray) + 1) As String
            TestArrayValue(UBound(TestArray)) = Chr(intCharCode)
        End If
    Next intCharCode
    Debug.Print TestArrayValue(LBound(TestArray)) _
    & " through " _
    & TestArrayValue(UBound(TestArray))
End Sub
Ben McCormack
Ben, this is very helpful. I didn't do `ReDim mstrTestArray` because I thought using the properties instead of the actual module level variable would be more "best practice." But I think you are right, there is no way to ReDim on an array returned by a reference. I suppose the alternative would be to use a local array variable in DoTest and set TestArray = strTestArray at the end of DoTest, even if it is a little less "real time." Thanks!
Kuyenda
I'm by no means a VBA expert, but I don't see anything wrong with using the `private` variable `mstrTestArray` from *within the class* to mutate its value. I think it could *possibly* get confusing if someone else is consuming your object and is confused that `mstrTestArray` mutated "inside the class." If you're going to be doing a lot of work in VBA, consider getting the **VBA Developer's Handbook** : http://www.amazon.com/VBA-Developers-Handbook-Ken-Getz/dp/0782119514
Ben McCormack
Does that book actually cover this stuff? I've never been able to find a book that is as thorough as this: http://www.cpearson.com/excel/mainpage.aspx. Thanks again Ben!
Kuyenda
The site you referenced looks like it has some real gems. The book I referenced also has some good code nuggets, but it's especially helpful at explaining in detail the *concepts* surrounding VBA. For example, on p. 380, there's a section entitled **Alternatives to Redim Preserve**: "...You'd do best to avoid ReDim Preserve if at all possible. What are the alternatives? One possibility is to use a collection..." . At less than $5 including shipping for a used copy, you can't go wrong with this book.
Ben McCormack
@Kuyenda I almost forgot: Be sure to get the latest edition (2nd, I think) of the VBA Developer's Handbook. (this edition might cost a little more, but still worth it IMHO)
Ben McCormack