【问题标题】:VBA: adding to collection which is a dictionary valueVBA:添加到作为字典值的集合
【发布时间】:2018-06-13 14:38:19
【问题描述】:

是否可以在 VBA 中将集合作为 `Scripting.Dictionary' 值,然后在循环中在找到特定键时向该集合添加新值?

类似:

Dim test_dict As New Scripting.Dictionary

For Each cell In ActiveSheet.Range("S2:S13")
    test_dict(cell.value).Add (cell.offset(1,0).value)
Next cell

另外,我需要考虑到键会重复的事实。

例如,在 Python 中,我可以将字典设置为将列表作为值,然后在每次迭代时附加到该列表:

dictionary= defaultdict(list)

for x in range(1,10):
    dictionary[x].append(x + 100)

【问题讨论】:

  • 显然 key 可以是 anything 除了数组
  • 上面的集合在哪里?
  • 这基本上是我的问题,我不知道如何告诉 VBA 对于这个特定的字典,键将是集合。我希望test_dict(cell.value) 成为一个集合,因此在上面的代码中使用test_dict(cell.value).Add
  • @QHarr - '显然键可以是数组以外的任何东西' ...或重复。
  • @barciewicz - 在那种情况下,我相信集合应该是字典项,而不是键。使用 key 作为标识符,使用 item 作为实际数据。

标签: vba excel


【解决方案1】:

喜欢下面的?

Option Explicit

Public Sub GetValues()
    Const col_1 = "col1", col_2 = "col2", col_3 = "col3"

    Dim lists As Object: Set lists = CreateObject("Scripting.Dictionary")

    lists.Add col_1, New Collection
    lists.Add col_2, New Collection
    lists.Add col_3, New Collection

    Dim currentCell As Range
    For Each currentCell In ActiveSheet.Range("S2:S13")
        Select Case currentCell.Value
        Case col_1
            lists(col_1).Add currentCell.Offset(, 1).Value
        Case col_2
            lists(col_2).Add currentCell.Offset(, 1).Value
        Case col_3
            lists(col_3).Add currentCell.Offset(, 1).Value
        End Select
    Next

    Dim key As Variant, item As Long

    For Each key In lists
        For item = 1 To lists(key).Count
            Debug.Print lists(key)(item)
        Next
    Next
End Sub

数据:

如果您事先不知道密钥,请使用:

Option Explicit
Public Sub GetValues()
    Dim lists As Object: Set lists = CreateObject("Scripting.Dictionary")
    Dim currentCell As Range
    For Each currentCell In ActiveSheet.Range("S2:S13")
        If Not lists.exists(currentCell.Value) Then lists.Add currentCell.Value, New Collection
        lists(currentCell.Value).Add currentCell.Offset(, 1).Value
    Next

    Dim key As Variant, item As Long
    For Each key In lists
        For item = 1 To lists(key).Count
            Debug.Print lists(key)(item)
        Next
    Next
End Sub

【讨论】:

    【解决方案2】:

    我想我明白你想要做什么。使用字典,您希望将键映射到项目集合。如果我的理解是正确的,请检查下面的代码,看看您是否可以修改它以满足您的需要。我对其进行了测试,它似乎有效。

    Sub LoadThem()
        Dim coll As New Collection
        Dim rng As Range
        Dim cel As Range
        Dim oDict As Object
    
        Set oDict = CreateObject("Scripting.Dictionary")
    
        Set rng = Range("A1:A26")
    
        For Each cel In rng
            If oDict.exists(cel.Value) Then
                oDict(cel.Value).Add cel.Offset(, 1).Value
            Else
                Set coll = New Collection
                coll.Add cel.Offset(, 1).Value
                oDict.Add cel.Value, coll
            End If
        Next cel
    
    
        For Each okey In oDict.keys
            Debug.Print okey
            For Each elem In oDict(okey)
                Debug.Print "    " & elem
            Next elem
        Next okey
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-07
      • 1970-01-01
      • 1970-01-01
      • 2017-10-02
      • 1970-01-01
      • 2021-12-30
      • 2020-08-07
      相关资源
      最近更新 更多