【问题标题】:Can I ReDim a module level array using a property?我可以使用属性重新调整模块级数组吗?
【发布时间】:2010-02-03 05:31:38
【问题描述】:

我认为我对如何通过 Property Get 和 Let 在 VBA 中处理模块级数组有很好的了解。有没有办法通过属性重新调整模块级数组?

以下代码在最后一个过程 (DoTest) 中的 ReDim 语句处出错。

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

谢谢!

【问题讨论】:

    标签: arrays vba class


    【解决方案1】:

    这是个好问题。我将在底部直接回答您的问题,但让我们从 VBA 中面向对象编程的简要背景开始。在大多数面向对象的语言中,属性通常看起来像一个字段,但行为像一个方法。这是什么意思?

    当你实例化一个类并为一个属性设置一个值时,它看起来像这样:

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

    在上面的代码中,MyProperty 看起来像一个字段,对吧?但是让我们看看它是如何在类中定义的:

    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
    

    正如您在上面的代码中看到的,虽然pMyProperty 是一个整数字段,但MyProperty 的公共GetSet 方法实际上看起来更像方法。属性“包裹”字段,尤其有助于设置对基础字段的访问。

    在您的示例中,您试图 ReDim 一个返回对数组的引用的属性。我不是 100% 确定,但我认为您不能在数组的 reference 上使用 ReDim

    我更改了您的代码以修改实际的私有字段mstrTestArray,它似乎工作正常。可以试试吗?

    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
    

    【讨论】:

    • 本,这很有帮助。我没有做ReDim mstrTestArray,因为我认为使用属性而不是实际的模块级变量会更“最佳实践”。但我认为你是对的,没有办法对引用返回的数组进行 ReDim。我想替代方法是在 DoTest 中使用局部数组变量并在 DoTest 结束时设置 TestArray = strTestArray,即使它的“实时性”稍差。谢谢!
    • 我绝不是 VBA 专家,但我认为使用 在类中 中的 private 变量 mstrTestArray 对其进行变异并没有什么问题价值。我认为如果其他人正在使用您的对象并且对mstrTestArray“在课堂内”发生变异感到困惑,它可能可能感到困惑。如果您要在 VBA 中做大量工作,请考虑获取 VBA 开发人员手册amazon.com/VBA-Developers-Handbook-Ken-Getz/dp/0782119514
    • 那本书真的涵盖了这些东西吗?我从来没有找到一本如此详尽的书:cpearson.com/excel/mainpage.aspx。再次感谢本!
    • 您引用的网站看起来有一些真正的宝石。我参考的这本书也有一些很好的代码块,但它特别有助于详细解释 VBA 的概念。例如,在 p。 380,有一个标题为 Redim Preserve 的替代方案 的部分:“...如果可能的话,您最好避免使用 ReDim Preserve。有哪些替代方案?一种可能性是使用集合.. 。”。这本书包括运费在内,不到 5 美元,绝对不会出错。
    • @Kuyenda 我差点忘了:一定要获得最新版本(我认为是第 2 版)的 VBA 开发人员手册。 (这个版本可能会贵一点,但恕我直言仍然值得)
    猜你喜欢
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 2013-03-14
    • 2020-01-19
    相关资源
    最近更新 更多