无法分配给数组

时间:2018-03-21 16:46:51

标签: excel vba

尝试初始化对象类。在对象中,我保留了计时器(人)的ID和一个RelatedTimekeepers数组。为此,我需要附加一个包含RelatedID列表的数组。

函数问题是AddRelatedTimekeeperNumber。目前,它没有通过注释行。

将这些内容添加到名为timekeeper的对象中。

我的班级看起来像:

' TIMEKEEPER CLASS
Private sTimekeeperNumber As String
Private sRelatedTimekeeperNumbers() As Variant

Public Property Let TimekeeperNumber(TimekeeperNumber As String)
    sTimekeeperNumber = TimekeeperNumber

End Property

Public Property Get TimekeeperNumber() As String
    TimekeeperNumber = sTimekeeperNumber

End Property

Public Sub AddRelatedTimekeeperNumber(RelatedTimkeeperNumber As String)
    Dim tmpArr() As String
    Dim i As Integer
    Dim sRelatedTimekeeperNumbersLength As Integer
    sRelatedTimekeeperNumbersLength = ArrayCount(sRelatedTimekeeperNumbers)
    ReDim tmpArr(1 To sRelatedTimekeeperNumbersLength) As String
    For i = 1 To sRelatedTimekeeperNumbersLength

        If i = sRelatedTimekeeperNumbersLength Then
            tmpArr(i) = RelatedTimekeeperNumber
        Else
            tmpArr(i) = sRelatedTimekeeperNumbers(i)
        End If

    Next i

    ReDim Preserve sRelatedTimekeeperNumbers(1 To ArrayCount(tmpArr))

    sRelatedTimekeeperNumbers = tmpArr ' <- "Can't Reassign to array, despite ReDim'ing"

End Sub

Public Sub PrintRelatedTimekeeperNumbers()
    Dim myArray() As Variant
    Dim txt As String
    Dim i As Long

    myArray = sRelatedTimekeeperNumbers

    For i = LBound(myArray) To UBound(myArray)
      txt = txt & myArray(i) & vbCrLf
    Next i

    MsgBox txt

End Sub

Function ArrayCount(ByRef vArray As Variant) As Long
    lArrayCount = UBound(vArray) - LBound(vArray) + 1

End Function

和我构建类的过程是:

Sub Init_Timekeepers()

    Dim oTimekeeper As New clsTimekeeper

    Dim sTkID As String
    oTimekeeper.TimekeeperNumber = "00089"
    oTimekeeper.AddRelatedTimekeeperNumber ("00089")
    sTkID = oTimekeeper.TimekeeperNumber

    oTimekeeper.AddRelatedTimekeeperNumber ("00091")
    oTimekeeper.AddRelatedTimekeeperNumber ("00092")

    oTimekeeper.PrintRelatedTimekeeperNumbers

End Sub

在设置数组之前,我认为我是ReDim,但编译器会在注释行抛出错误。

1 个答案:

答案 0 :(得分:3)

已修改以添加有关其余代码的一些提示

关于你问题的问题,只是暗淡

Private sRelatedTimekeeperNumbers  As Variant

BTW显示的代码有两个拼写错误:

lArrayCount = UBound(vArray) - LBound(vArray) + 1

应该是

ArrayCount = UBound(vArray) - LBound(vArray) + 1

Public Sub AddRelatedTimekeeperNumber(RelatedTimkeeperNumber As String)

应该是

Public Sub AddRelatedTimekeeperNumber(RelatedTimekeeperNumber As String)

根据您的方案说明,我要说您需要对代码进行以下更改(以及随后的重构):

  1. 处理sRelatedTimekeeperNumbers最初为空

    然后您必须将ArrayCount更改为:

    Function ArrayCount(ByRef vArray As Variant) As Long
        If IsEmpty(vArray) Then
            ArrayCount = 0
        Else
            ArrayCount = UBound(vArray) - LBound(vArray) + 1
        End If
    End Function
    
  2. 向数组添加新元素

    然后将AddRelatedTimekeeperNumber(RelatedTimekeeperNumber As String)更改为:

    Public Sub AddRelatedTimekeeperNumber(RelatedTimekeeperNumber As String)
        Dim sRelatedTimekeeperNumbersLength As Long
    
        sRelatedTimekeeperNumbersLength = ArrayCount(sRelatedTimekeeperNumbers)
        If sRelatedTimekeeperNumbersLength = 0 Then
            ReDim sRelatedTimekeeperNumbers(1 To 1) As String
        Else
            ReDim Preserve sRelatedTimekeeperNumbers(1 To sRelatedTimekeeperNumbersLength + 1) As String
        End If
        sRelatedTimekeeperNumbers(sRelatedTimekeeperNumbersLength + 1) = RelatedTimekeeperNumber
    End Sub
    

    最后,将PrintRelatedTimekeeperNumbers()更改为:

    Public Sub PrintRelatedTimekeeperNumbers()
        If UBound(sRelatedTimekeeperNumbers) > 0 Then
            MsgBox Join(sRelatedTimekeeperNumbers, " ")
        Else
            MsgBox "no time keepers related to " & sTimekeeperNumber
        End If
    End Sub
    
  3. 但您通过采用其他对象而不是数组(例如CollectionDictionary对象

    )更进了一步

    在前一种情况下,您的类代码将压缩为:

        Option Explicit
    
        Private sTimekeeperNumber As String
        Private sRelatedTimekeeperNumbers As New Collection
    
        Public Property Let TimekeeperNumber(TimekeeperNumber As String)
            sTimekeeperNumber = TimekeeperNumber        
        End Property
    
        Public Property Get TimekeeperNumber() As String
            TimekeeperNumber = sTimekeeperNumber        
        End Property
    
        Public Sub AddRelatedTimekeeperNumber(RelatedTimekeeperNumber As String)            
            sRelatedTimekeeperNumbers.Add RelatedTimekeeperNumber
        End Sub
    
        Public Sub PrintRelatedTimekeeperNumbers()
            Dim item As Variant
            Dim txt As String
            If sRelatedTimekeeperNumbers.count > 0 Then
                For Each item In sRelatedTimekeeperNumbers
                    txt = txt & item & " "
                Next
                MsgBox Trim(txt)
            Else
                MsgBox "no time keepers related to " & sTimekeeperNumber
            End If
        End Sub
    

    在后一种情况下它会变成:

        Option Explicit
    
        Private sTimekeeperNumber As String
        Private sRelatedTimekeeperNumbers As New Scripting.Dictionary
    
        Public Property Let TimekeeperNumber(TimekeeperNumber As String)
            sTimekeeperNumber = TimekeeperNumber
    
        End Property
    
        Public Property Get TimekeeperNumber() As String
            TimekeeperNumber = sTimekeeperNumber
    
        End Property
    
        Public Sub AddRelatedTimekeeperNumber(RelatedTimekeeperNumber As String)
            sRelatedTimekeeperNumbers.Add RelatedTimekeeperNumber, ""
        End Sub
    
        Public Sub PrintRelatedTimekeeperNumbers()
            Dim item As Variant
            Dim txt As String
            If sRelatedTimekeeperNumbers.count > 0 Then
                MsgBox Join(sRelatedTimekeeperNumbers.Keys, " ")
            Else
                MsgBox "no time keepers related to " & sTimekeeperNumber
            End If
        End Sub