从类VBA中的数组成员获取对象

时间:2018-10-27 20:56:09

标签: excel vba excel-vba

我有一个名为cSchedule的类对象,其中包含一个成员pTimeline,该成员是cDay对象的数组。我正在尝试使用pTimeline的Get Property返回特定索引处的cDay对象,但出现以下错误“运行时错误'438':对象不支持该属性或方法”

我正在从我的主模块中调用此函数,如下所示:

Dim TestDay As cDay
Set TestDay = TestSchedule.Timeline(1)

我已经验证了TestSchedule包含所有正确的数据,所以问题在于我如何尝试在pTimeline的特定索引处获取cDay对象的引用。

' Class Module: cSchedule

Private pTimeline() As cDay
Private pFitness As Double
Private pMap As Collection
'Number of units the timeline is divided into. E.g if weeks, pNumTimeUnits should be 52*numYears
Private pNumTimeUnits As Integer


''''''''''''''''''''''
' Timeline property
''''''''''''''''''''''
Public Property Get Timeline(Optional argIndex As Variant) As Variant
    If IsMissing(argIndex) Then
        Timeline = pTimeline
    Else
        Dim selectedDay As Variant
        selectedDay = pTimeline(argIndex).Copy
        Set Timeline = selectedDay
    End If
End Property
Public Property Let Timeline(Optional argIndex As Variant, arrValue As Variant)
    Dim arrLength As Integer
    Dim intIndex As Integer

    ' Resize array if incoming list of activities is greater than current
    arrLength = (UBound(arrValue) - LBound(arrValue) + 1)
    If arrLength <> pNumTimeUnits Then
        ReDim Preserve pTimeline(arrLength)
        pNumTimeUnits = arrLength
    End If
    pTimeline = arrValue
End Property

任何人都能够洞悉我做错了什么以及正确的方法是从包含对象数组的类成员中获取对象吗?

1 个答案:

答案 0 :(得分:0)

恐怕您的代码有些不正确。

问题之一是您在同一属性中返回了数组和类,这虽然不是一个好习惯,但还会迫使您将属性作为Variant的形式返回,有时需要使用关键字Set,因为返回的值有时是一个对象。

一种更好的方法可能是具有两个属性:一个属性获取并设置数组,另一个属性获取该数组的单个成员。这样,您的 cSchedule 类的缩写版本可能看起来像这样:

Option Explicit

Private pTimelines() As cDay
Private pTimeline() As cDay
Private pNumTimeUnits As Long

Public Property Get Timelines() As Variant
    Timelines = pTimelines
End Property

Public Property Let Timelines(RHS As Variant)
    pTimelines = RHS
    pNumTimeUnits = UBound(RHS) - LBound(RHS) + 1
End Property

Public Property Get TimelineAt(idx As Long) As cDay
    Set TimelineAt = pTimelines(idx)
End Property

第二,您的Timeline设置例程可能没有按照您的想象做。即使您使用Redim Preserve来调整数组的大小,后面的行pTimeline = arrValue也会覆盖并确实调整该数组的大小。因此,该行以上的所有代码都是多余的。

最后,我怀疑引发错误的代码在selectedDay = pTimeline(argIndex).Copy行中。没有看到您的cDay类,我们不能肯定地说,但是如果该Copy函数返回一个cDay类,那么您将需要Set关键字-再次,如果您经常使用Variant,这就是您遇到的问题之一。

我个人将pTimelines定义为Collection,但无论如何,下面显示了一些示例模块代码来向您展示上述功能:

Dim testSchedule As cSchedule
Dim t() As cDay
Dim i As Long

Set testSchedule = New cSchedule

ReDim t(51)
For i = 0 To 51
    Set t(i) = New cDay
    t(i).TheDate = DateAdd("w", i, DateSerial(2018, 1, 1))
Next

testSchedule.Timelines = t

Debug.Print testSchedule.TimelineAt(0).TheDate

出于本演示的目的,我编写了以下的cDay类,但此示例未实现MyCopy函数:

Option Explicit

Private pTheDate As Date

Public Property Get TheDate() As Date
    TheDate = pTheDate
End Property

Public Property Let TheDate(RHS As Date)
    pTheDate = RHS
End Property

Public Function MyCopy() As cDay
    Set MyCopy = New cDay
    MyCopy.TheDate = pTheDate
End Function