Получение объекта из члена массива в классе VBA - PullRequest
0 голосов
/ 27 октября 2018

У меня есть объект класса cSchedule, который содержит член pTimeline, который является массивом объектов cDay. Я пытаюсь использовать свойство Get свойства pTimeline, чтобы вернуть объект cDay с определенным индексом, но я получаю следующую ошибку «Ошибка времени выполнения« 438 »: объект не поддерживает это свойство или метод» .

Я вызываю эту функцию из моего основного модуля следующим образом

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

Я проверил, что TestSchedule содержит все необходимые данные, поэтому проблема в том, как я пытаюсь получить ссылку на объект cDay по определенному индексу pTimeline.

' 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 голосов
/ 28 октября 2018

Боюсь, что в вашем коде справедливо не совсем верно.

Одна из проблем заключается в том, что у вас есть массивы и классы, возвращаемые в одном свойстве, что в любом случае не очень хорошая практика, нотакже вынуждает вас возвращать свойство как 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 s слишком часто.

Лично я бы определил 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...