【问题标题】:Collections in dictionaries字典中的集合
【发布时间】:2017-08-28 10:54:50
【问题描述】:

我想创建一个汽车制造商列表及其型号。 为此,我使用字典,其中键是品牌,项目是模型的集合。例如: 字典中的key是“Volkswagen”,集合包含polo、cc、passat等…… 该代码从工作表中读取项目。问题是我不确定集合是否加载了模型类型。此外,我检查了调试选项,如何从字典中写出集合元素,但我得到了空消息。如果有人可以帮助我修复此代码,我将非常高兴。

Sub collectModels()

Dim imp_wb As Workbook, new_wb As Workbook
Dim ws_imp As Worksheet, ws_new As Worksheet, ws_stnd As Worksheet, ws_model_list As Worksheet
Dim lastRow As Long, lastCol As Long
Dim rng As Range
Dim validate As String, model_key As String, model_item As String
Dim modelCollection As Collection


Set imp_wb = ThisWorkbook
Set ws_model_list = imp_wb.Sheets("MODEL_LIST")

'Set new_wb = Workbooks.Add
'Set ws_new = new_wb.Worksheets(1)

Set rng = ws_stnd.Range("A2:A68")

'ws_imp.Activate
ws_model_list.Activate
lastRow = Last(1)
lastCol = Last(2)

Set dict_ModelMapping = CreateObject("scripting.dictionary")
Set modelCollection = New Collection


For i = 1 To lastCol

model_key = ws_model_list.Cells(1, i).Value

    For j = 2 To lastRow

        'add items to collection
        model_item = ws_model_list.Cells(j, i).Value


        If Not model_item = "" Then
            modelCollection.Add model_item
        Else
            'add collection to dictionary
            dict_ModelMapping.Add model_key, modelCollection
            Set modelCollection = New Collection
            GoTo nextColumn
        End If
    Next j

nextColumn:

'DEBUG CODE
    For Each v In dict_ModelMapping.Key("SUZUKI")
        Debug.Print v
    Next v
Next i


'--- CHECK COLLECTIONS---

Dim tmpCollection As Collection
Dim showItem As String

For Each Key In dict_ModelMapping.Keys

    MsgBox ("--------------" & Key & "---------------")


Next

End Sub

【问题讨论】:

  • 什么是Last
  • @SJR the Last 是一个函数,它返回工作表中 Last(1) 最后一行、Last(2) 最后一列、Last(3) 最后使用的单元格。这是由 ron de burin 创建的。

标签: vba excel dictionary collections


【解决方案1】:

我已经更正了一些问题,并且对其他人不屑一顾,以使您的代码能够正常工作。使用 option explicit 指令是个好主意,因为它有助于调试:

Option Explicit


Sub collectModels()

  Dim imp_wb As Workbook
  Dim ws_model_list As Worksheet
  Dim lastRow As Long, lastCol As Long

  Dim model_key As String, model_item As String
  Dim modelCollection As Collection

  Set imp_wb = ThisWorkbook
  Set ws_model_list = imp_wb.Sheets("MODEL_LIST")

  With ws_model_list
    lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column

    Dim dict_ModelMapping As Object
    Set dict_ModelMapping = CreateObject("scripting.dictionary")

    Dim i As Integer, j As Integer
    For i = 1 To lastCol
      model_key = .Cells(1, i).Value
      Set modelCollection = New Collection
      lastRow = .Cells(.Rows.Count, i).End(xlUp).Row
      For j = 2 To lastRow
        'add items to collection
        model_item = .Cells(j, i).Value
        If model_item <> "" Then
          modelCollection.Add model_item
        End If
      Next j
      'add collection to dictionary
      dict_ModelMapping.Add model_key, modelCollection
    Next i

  End With

  'DEBUG CODE
  Dim v As Variant
  Dim coll As Collection
  Set coll = dict_ModelMapping("SUZUKI")
  For Each v In coll
    Debug.Print v
  Next v

  '--- CHECK COLLECTIONS---
  Dim key As Variant
  For Each key In dict_ModelMapping.Keys
    MsgBox ("--------------" & key & "---------------")
  Next

End Sub

【讨论】:

  • 我在代码中发现了 2 个错误。循环 j 必须包含 else 才能处理现有的字典键,因为每个模型下的行不一致。因此,当它到达一个空单元格时,它必须跳转到下一列。另一个错误是 v 循环。运行时错误“438”对象不支持此属性或方法。所以基本上它不能写出集合。还有其他想法吗?
  • 我已将“lastRow”行移到循环中,以便它现在可以正确找到每列的最后一行。此外,我已将字典的值显式设置为集合,以便现在该循环将打印出集合中的每个项目。 'Set coll' 设置对集合的引用(请注意,我们没有使用 'new'),因此 coll 指向它。现在您应该能够正确地遍历“SUZUKI”的集合。让我知道这是否适合您。
【解决方案2】:

处理空单元格很重要。一旦列表结束,代码就会将字典与集合一起保存。要引用字典中的集合,您必须在循环中创建一个循环。

ws_model_list.Activate
lastRow = Last(1)
lastCol = Last(2)

Set dict_ModelMapping = CreateObject("scripting.dictionary")

For i = 1 To lastCol

model_key = ws_model_list.Cells(1, i).Value
Set modelCollection = New Collection
    For j = 2 To lastRow

        'add items to collection
        model_item = ws_model_list.Cells(j, i).Value

        If model_item <> "" Then
            modelCollection.Add model_item
        Else
            'add collection to dictionary
            dict_ModelMapping.Add Key:=model_key, Item:=modelCollection
            GoTo nextColumn
        End If

    Next j

nextColumn:

Next i



Dim v1 As Variant, v2 As Variant
    For Each v1 In dict_ModelMapping.Keys
        For Each v2 In dict_ModelMapping(v1)
            MsgBox (v2)
        Next v2
   Next v1

【讨论】:

    【解决方案3】:

    这是一个最小的例子:

    • 创建字典
    • 使用String 键创建集合并添加到字典
    • 迭代字典的每一项
    • 打印每个集合中作为字典值的项目

    您可以调整示例代码以适合您的工作表:

    Option Explicit
    
    Sub TestDictionaryOfCollections()
    
        Dim dic As Object
        Dim coll As Collection
        Dim str As String
        Dim var1 As Variant, var2 As Variant
    
        ' instantiate the dictionary
        Set dic = CreateObject("Scripting.Dictionary")
    
        ' VW
        Set coll = New Collection
        coll.Add "Golf"
        coll.Add "Polo"
        coll.Add "Passat"
        coll.Add "Tiguan"
        dic.Add Item:=coll, Key:="VW"
    
        ' Ford
        Set coll = New Collection
        coll.Add "Fiesta"
        coll.Add "Falcon"
        coll.Add "Mondeo"
        coll.Add "Sierra"
        dic.Add Item:=coll, Key:="Ford"
    
        ' debug
        For Each var1 In dic.Keys
            For Each var2 In dic(var1)
                Debug.Print var2
            Next var2
        Next var1
    
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-14
      • 1970-01-01
      • 2019-07-21
      • 2017-07-14
      • 2016-01-13
      • 1970-01-01
      相关资源
      最近更新 更多