从字典返回类属性的数组

时间:2019-11-13 13:55:53

标签: arrays excel vba class dictionary

背景:

在最近尝试回答question时,我一直在想是否有可能直接从字典项中返回一组类对象属性。

代码:

TstClass想象成一个具有以下代码的类模块:

Public val1 As Variant
Public val2 As Variant
Public val3 As Variant

然后这段代码进行测试:

Sub Test()

Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
Dim lst As TstClass, key As Variant, arr As Variant

For x = 1 To 3
    Set lst = New TstClass
    lst.val1 = "A" & x
    lst.val2 = "B" & x
    lst.val3 = "C" & x
    dict.Add x, lst
Next x

For Each key In dict
    arr = Array(dict(key).val1, dict(key).val2, dict(key).val3)
Next key

End Sub

问题:

在上述情况下,Array(dict(key).val1, dict(key).val2, dict(key).val3)可以很好地返回数组,但是如果我们想到val4-val50,它将变成更多的代码。用Array(...)或逐行Debug.Print Dict(key).Valx写出来。

问题:

是否可以直接从字典键的类对象属性返回数组?对我来说,最明显的尝试是arr = Dict(key)希望它能以某种方式识别出我需要该物品的所有属性。最重要的是,不允许将常量,数组和用户定义的类型声明为Public,因此类似Public Vals(0 to 2)的方法也不起作用。

谢谢你, JvdV

2 个答案:

答案 0 :(得分:1)

不确定这是否完全符合您的要求,但是可以在类中创建一个方法来构建所需属性的数组。然后,您可以在该类的每个实例上调用它以获取数组详细信息。

类-名为“示例”:

Public val1 As Variant
Public val2 As Variant
Public val3 As Variant

Public Function GetArray() As Variant
    GetArray = Array(Me.val1, Me.val2, Me.val3)
End Function

客户代码-在标准模块中:

Sub SOExample()

    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
    Dim lst As Example, arr As Variant, key As Variant

    For x = 1 To 3
        Set lst = New Example
        lst.val1 = "A" & x
        lst.val2 = "B" & x
        lst.val3 = "C" & x
        dict.Add x, lst
    Next

    For Each key In dict.keys
        arr = dict(key).GetArray
        Debug.Print Join(arr, ",")
    Next

End Sub

输出:

A1,B1,C1
A2,B2,C2
A3,B3,C3

答案 1 :(得分:0)

从@RyanWildry的答案中汲取灵感,我发现,尽管无法使用Public变体数组,我们仍然可以使用Private数组。因此,我做到了Property Let会将值分配给数组中的特定索引。

创建一个Public Function以返回Private数组变量,然后将一次性返回该数组。


类模块,名为TstClass

Private vals(0 To 2) As Variant

Public Property Let val(ByVal x As Long, ByVal NewVal As Variant)
    vals(x) = NewVal
End Property

Public Function GetArray() As Variant
    GetArray = vals
End Function

Module1下的代码

Sub Test()

Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
Dim lst As TstClass, key As Variant, arr As Variant

For x = 1 To 3
    Set lst = New TstClass
    lst.val(0) = "A" & x
    lst.val(1) = "B" & x
    lst.val(2) = "C" & x
    dict.Add x, lst
Next x

For Each key In dict
    arr = dict(key).GetArray
Next key

End Sub

另一种方法是不使用Class模块的概念,而使用(例如)ArrayList对象:

Sub Test()

Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
Dim lst As Object: Set lst = CreateObject("System.Collections.ArrayList")
Dim arr As Variant

For x = 1 To 3
    lst.Add "A" & x
    lst.Add "B" & x
    lst.Add "C" & x
    dict.Add x, lst.Toarray
    lst.Clear
Next x

For Each key In dict
    arr = dict(key)
Next key

End Sub

但是,后一种方法将超越此问题的目的。

与直接从字典项返回数组一样,这与我所能接近的非常接近。我很高兴收到建设性的反馈意见或其他更好的方式,因为Class模块对我来说还很陌生,但这仍然无法回答有关如何直接返回属性数组的问题的本质。