Arrays 如何更改作为字典项的类模块的数组元素?

Arrays 如何更改作为字典项的类模块的数组元素?,arrays,excel,vba,class,dictionary,Arrays,Excel,Vba,Class,Dictionary,我所拥有的: with sh1 For i = 2 To .UsedRange.Rows.count If sData.Exists(.Cells(i, rCol).Value2) Then Set cls = sData(.Cells(i, rCol).Value2) Else Set cls = New cls_Source_Attributes sData.Add .Cells(i, rC

我所拥有的:

with sh1
    For i = 2 To .UsedRange.Rows.count
       If sData.Exists(.Cells(i, rCol).Value2) Then
           Set cls = sData(.Cells(i, rCol).Value2)
       Else
           Set cls = New cls_Source_Attributes
           sData.Add .Cells(i, rCol).Value2, cls
       End If
    
       cls.idRow = i
       cls.arrAtt = .Range("" & .Cells(i, firstCol).Address & ":" & .Cells(i, lastCol).Address & "")
    Next i
End With
  • 字典(sData)
  • sData中的所有项都是类模块(cls)的实例
  • 类模块的每个实例都包含一个2D数组(cls.arrAtt)
  • arrAtt在类模块中声明为公共变量
  • VBA的基本知识
  • 我想做什么:

    with sh1
        For i = 2 To .UsedRange.Rows.count
           If sData.Exists(.Cells(i, rCol).Value2) Then
               Set cls = sData(.Cells(i, rCol).Value2)
           Else
               Set cls = New cls_Source_Attributes
               sData.Add .Cells(i, rCol).Value2, cls
           End If
        
           cls.idRow = i
           cls.arrAtt = .Range("" & .Cells(i, firstCol).Address & ":" & .Cells(i, lastCol).Address & "")
        Next i
    End With
    
    将数组的所有“true”和“false”元素替换为“Yes”和“No”

    (如果正确触发语句)

    正如图中所示,在数组中循环不会改变它的元素

    你知道为什么吗

    以下是数组的填充方式:

    with sh1
        For i = 2 To .UsedRange.Rows.count
           If sData.Exists(.Cells(i, rCol).Value2) Then
               Set cls = sData(.Cells(i, rCol).Value2)
           Else
               Set cls = New cls_Source_Attributes
               sData.Add .Cells(i, rCol).Value2, cls
           End If
        
           cls.idRow = i
           cls.arrAtt = .Range("" & .Cells(i, firstCol).Address & ":" & .Cells(i, lastCol).Address & "")
        Next i
    End With
    
    您必须向类中添加一个“方法”,例如

    Public Sub arrAttChange(i As Long, j As Long, val As Variant)
        arrAtt(i, j) = val
    End Sub 
    
    然后在代码中使用它,如下所示:

    For Each key In sData
        Set cls = sData(key)
        For j = LBound(cls.arrAtt, 2) To UBound(cls.arrAtt, 2)
            If cls.arrAtt(1, j) = "true" Then cls.arrAttChange 1, j, "Yes"
            If cls.arrAtt(1, j) = "false" Then cls.arrAttChange 1, j, "No"
        Next
    Next key
    
    从逻辑角度来看,此代码的增强可能是

    For Each key In sData
        Set cls = sData(key)
        With cls ' <-- reference the object
    
            For j = LBound(.arrAtt, 2) To UBound(.arrAtt, 2)
                Select Case .arrAtt(1, j)
                    Case "true"
                        .arrAttChange 1, j, "Yes"
    
                    Case "false"
                        .arrAttChange 1, j, "No"
                End Select
            Next
    
        End With
    Next
    

    很抱歉我的反馈太晚了。谢谢你的快速回答和建议。你能给我解释一下为什么它是这样工作的,而不是我尝试过的方式吗?为什么cls.arrAtt=arrAtt工作(最后一行),而cls.arrAtt(1,j)=“No”不工作?我认为这是一样的。@HYs,我还不知道真正的深层原因,但我的猜测是,
    Variant
    类型的
    Public
    成员只能作为一个“整体”分配,就像你自己对
    cls.arrAtt=.Range(“&.Cells(I,firstCol.Address&.”和.Cells(I,lastCol.Address&”)所做的那样
    。而可以在其“详细信息”中查询