【问题标题】:Recursively print next dictonaries in VBA在 VBA 中递归打印下一个字典
【发布时间】:2014-11-12 14:26:08
【问题描述】:

我想在 VBA 中打印嵌套字典。基本上我有一个Dictionary,其中每个键都是String,但每个值可以是String 或另一个Dictionary

说我的Dictionary 获得了价值

{ "FOO" => "BAR" , "HELLO" => { "WORLD => ":)", "OTHER" => ":(" } }

我想在 Excel 电子表格中显示:

FOO  |BAR  |
HELLO|WORLD|:)
HELLO|OTHER|:(

我的问题是我需要找到一种方法来猜测每个键下的值的类型,所以当我调用dict("HELLO") 时,我可以显示该值是字符串还是字典调用再次相同的功能。

为此,我需要知道:

  • 如果有办法知道字典中存储的值的类型是什么
  • 如果有办法将该值转换为目标类型(字符串或字典)

这就是我尝试过的方法

Function display_dictionary(dict As Scripting.Dictionary, out As Range) As Integer

  Dim vkey As Variant
  Dim key As String
  Dim row_offset As Integer
  Dim value As Object
  Dim svalue As String
  Dim dvalue As Dictionary
  Dim each_offset  As Integer

  row_offset = 0

  For Each vkey In dict.Keys()
    key = vkey
    Set value = dict(key)
    if value is String then
       svalue = ???
       out.offset(row_offset, 0).value = key
       out.offset(row_offset, 1).value = svalue
       row_offset = row_offset + 1
    else if value is Dictionary
       dvalue = ???
       each_offset = display_dictionary(dvalue, out.offset(row_offset, 1))
       For each_row = 0 To each_offset - 1
        out.offset(row_offset + each_row) = key
       Next
       row_offset = row_offset + each_offset
    End If
  Next

End

【问题讨论】:

    标签: excel vba recursion dictionary data-structures


    【解决方案1】:

    我实际上打算提出一种不同的方式来显示结果。我认为这更合乎逻辑,但欢迎您对其进行修改以满足您的特定需求。就像提示打印节点的逻辑树,如下所示,然后在需要时操作结果。

    例如,树看起来像这样(请注意,我添加了一个深度级别

    以及要重现的代码

    Private i As Long
    Private depth As Long
    
    Sub Main()
    Cells.ClearContents
    
        Dim dict As New Dictionary
        Dim subDict As New Dictionary
        Dim lvlDict As New Dictionary
    
        lvlDict.Add "LVL KEY", "LVL ITEM"
    
        subDict.Add "HELLO", ":)"
        subDict.Add "WORLD", ":("
        subDict.Add "OTHER", lvlDict
    
        dict.Add "FOO", "BAR"
        dict.Add "BOO", subDict
    
        i = 1
        depth = 0
        TraverseDictionary dict
    
        Columns.AutoFit
    
    End Sub
    
    Private Sub TraverseDictionary(d As Dictionary)
    
        For Each Key In d.Keys
            Range("A" & i).Offset(0, depth) = "KEY: " & Key
            If VarType(d(Key)) = 9 Then
                depth = depth + 1
                TraverseDictionary d(Key)
            Else
                Range("B" & i).Offset(0, depth) = "ITEM: " & d(Key)
            End If
            i = i + 1
        Next
    End Sub
    

    和电子表格结果:


    要获取变量类型或其类型名称,您可以使用:

    Debug.Print TypeName(dict("HELLO")), VarType(dict("HELLO"))
    

    【讨论】:

    • 我想遍历字典并不是很困难,其中项目也可以是字典,问题是你将如何在电子表格上按照你想要的方式打印它:>
    • +1 非常棒的工作!如果字典的Item 本身是一个对象而不是字典,则风险很小。具体来说,VarType(d(Key)) = 9 适用于任何类型的Objects(我尝试使用自定义类并返回类型不匹配错误)。我建议在检查VarType 之后,还要专门检查字典(例如,尝试访问属性并捕获错误)。
    • @Ioannis 我已经在CodeReview上发布了这个供进一步讨论
    • 抱歉,如果评论太晚了......如何遍历和打印包含集合对象的嵌套字典?使用上面的 TraverseDictionary 代码如何做到这一点? Typename 也是一个更好的对象类型指示符还是 TypeOf 一个好的指示符?
    猜你喜欢
    • 2020-07-14
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多