使用数组VBA初始化对象

时间:2018-01-09 16:34:30

标签: arrays vba excel-vba oop excel

我正在尝试创建一个包含数组的类,而且我在为它创建类时遇到了问题...

CLASS:

Private pST(0 To 2) As String

Public Property Get ST() As String
   ST() = pST()
End Property
Public Property Let ST(value() As String)  '<---- ERROR HERE
   pST() = value()
End Property

CODE RUN:

Sub test()

   Dim foo As cPurchaseOrder
   Set foo = New cPurchaseOrder

   foo.ST(0) = "test"

   Debug.Print foo.ST(0)

End Sub

错误:

  

编译错误:

     

同一属性的属性过程的定义不一致,或者属性过程具有可选参数,ParamArray或无效的Set final参数。

问题:

如何正确地将数组初始化为变量?

编辑: 与Mat的Mug回复有关

CLASS CHANGED:

Private pST As Variant

Public Property Get STContent(ByVal index As Long) As String
    STContent = pST(index)
End Property

Public Property Let STContent(ByVal index As Long, ByVal value As String)
    pST(index) = value
End Property

Private Sub Class_Initialize()
   ReDim pST(0 To 2)
End Sub

CODE RUN TO TEST:

Sub test()

   Dim foo As cPurchaseOrder
   Set foo = New cPurchaseOrder

   foo.STContent(0) = "test" '<--- Type mismatch here

   Debug.Print foo.STContent(0)

End Sub

3 个答案:

答案 0 :(得分:5)

你的getter需要返回一个String()数组,以使类型保持一致:

Public Property Get ST() As String()

但是我不建议像这样暴露一个数组。首先是因为分配类型化数组非常痛苦,其次是因为setter(Property Let)实际上在这里作弊:

Public Property Let ST([ByRef] value() As String)

除非您明确指定ByVal,否则参数始终在VBA中传递ByRef ...除非有Property Let的这个怪癖 - RHS / value参数始终为在运行时通过ByVal

数组只能传递ByRef

因此,获取(或实际分配)整个数组的属性并没有多大意义。

更好的方法是封装数组(尽管我将其设为Variant),并通过索引属性:

Private internal As Variant 'String array

'...

Public Property Get Content(ByVal index As Long) As String
    Content = internal(index)
End Property

Public Property Let Content(ByVal index As Long, ByVal value As String)
    internal(index) = value
End Property

答案 1 :(得分:2)

那里有很多问题。

首先,您的Property Get需要返回一个String数组。其次,您的数组需要是动态的,或者您需要重写整个事物以便将索引值传递给它,否则无法指示您传递给数组的值。因此,例如,使用动态数组:

Private pST() As String

Public Property Get ST() As String()
   ST = pST
End Property
Public Property Let ST(value() As String)
   pST() = value()
End Property

和调用代码:

Sub test()

   Dim foo As cPurchaseOrder
   Set foo = New cPurchaseOrder
   Dim asData() As String
   ReDim asData(0)
   asData(0) = "test"

   foo.ST = asData

   Debug.Print foo.ST()(0)

End Sub

不幸的是,我无法确定原意是什么意思。

答案 2 :(得分:0)

现在已经很晚了但是试一试。在模块中:

Option Explicit

Sub Test()

   Dim foo As cPurchaseOrder
   Set foo = New cPurchaseOrder
   foo.AddValueToSt "test", 1
   Debug.Print foo.ST(1)

End Sub

在班级中:

Option Explicit

Private pST

Public Property Get ST() As Variant
   ST = pST
End Property

Public Property Let ST(value As Variant)
   pST = value
End Property

Public Function AddValueToSt(value As Variant, position As Long)
    pST(position) = value
End Function

Private Sub Class_Initialize()
    ReDim pST(2)
End Sub

这是我使用Factory Method Pattern的方法。当我说“我的方式”时,对我来说这个模式被翻译为“每当一些OOP需要超过5分钟的思考时才添加一个函数。”