Excel VBA – 如何创build和转储数组复杂结构的散列?

我来自Perl的背景和学习Excel-VBA。 在Perl中,我们可以使用Data :: Dumper来获取数据结构的转储。

这里是来自Perl的例子:

use strict; use Data::Dumper; my $hash={}; $hash->{key1} = [ 1, "b", "c" ]; # the value stored against key1 here is an array $hash->{key2} = [ 4.56, "g", "2008-12-16 19:10 -08:00" ]; # the value stored against key2 here is an array my $hash2={1=>['one','ONE']}; # this is a hash $hash->{key3}=$hash2; # the value stored against key3 here is a hash print Dumper($hash)."\n"; 

它产生以下输出:

 $VAR1 = { 'key2' => [ '4.56', 'g', '2008-12-16 19:10 -08:00' ], 'key1' => [ 1, 'b', 'c' ], 'key3' => { '1' => [ 'one', 'ONE' ] } }; 

正如我前面提到的,我是Excel-VBA的新手和学习它,所以请耐心帮助我达到以下问题的答案:

  1. 在Excel-VBA中是否有类似于perl的Data :: Dumper的东西?
  2. 如何使用Scripting.Dictionary对象在Excel-VBA中创build一个与上面完全类似的结构(即$ hash)? 如何迭代该结构并检索存储在键上的值? 这种结构是否支持“存在”,“删除”,“添加”等方法?

我不知道有一个内置的机制,会做你所问的。 你将不得不创build一个“keyedArray”类来实现你想要的方法。 弄清楚这一点将会使你牢牢掌握VBA的学习曲线。

一个好的开始将是http://www.cpearson.com/excel/classes.aspx

如果这对你没有帮助的话,可以在评论中说出来 – 我可能在稍后时间把一个简短的例子放在一起。

你可能有三个需求之一:

  1. 交互式debugging – 然后在debugging器中添加一个断点,使用vba中的添加监视,并迭代地展开结构
  2. 获取数据到文本文件进行一些后期处理 – 查找xml或json导出器
  3. 像显示的一样获取数据,例如用Safe导入Perl。 – 那么你需要自己编写一个recursion过程。

后者将是相当困难的,因为大多数vba结构(除非你自己做),有圆环。 (如children => […],parent => FIX)。

VBA集合不给你足够的支持,所以字典是你所需要的。 (记得工具 – >引用到“Miscrosoft脚本运行”)

以下是不完美的,但可能会给你一个开始

 Option Explicit ' aka use strict Option Base 0 ' to be close to perl Sub test() Dim c As New Dictionary Dim c2 As New Dictionary Dim a(10) As Variant, b() As Variant a(1) = 1.1 a(2) = "array item 1" ReDim b(0) b(0) = 41.9 ReDim Preserve b(UBound(b) + 1) ' aka push b(UBound(b)) = 41.95 ReDim Preserve b(UBound(b) + 1) b(UBound(b)) = 41.96 '#build a structure c.Add item:="val1.2", Key:="key1.2" c.Add item:="val1.1", Key:="key1" c2.Add item:="val2.1", Key:="key2.1" c2.Add item:=42, Key:="key2.2" c2.Add item:=42.1, Key:="key2.3" c2.Add item:=a, Key:="key2.4" c2.Add item:=b, Key:="key2.5" 'add c2 to c to make it hierarchical c.Add item:=c2, Key:="key1.3""" Debug.Print vba2perl(c) End Sub Function vba2perl(item, Optional indent = 0) Dim txt Dim Key, I Select Case TypeName(item) Case "Dictionary" indent = indent + 1 txt = txt _ & vbCrLf & Space(indent * 4 - 2) & "{" For Each Key In item txt = txt _ & vbCrLf & Space(indent * 4) & Key & " => " & vba2perl(item(Key), indent) & "," Next Key txt = txt _ & vbCrLf & Space(indent * 4 - 2) & "}" Case "String" txt = item txt = Replace(txt, """", "\""") ' more escaping needed txt = """" & txt & """" Case "Integer" txt = item Case "Double" txt = item txt = Replace(txt, ",", ".") ' if regional, then fix . vs , tbd Case "Empty" txt = "undef" Case "Variant()" indent = indent + 1 txt = txt _ & vbCrLf & Space(indent * 4 - 2) & "[" For I = LBound(item) To UBound(item) txt = txt _ & vbCrLf & Space(indent * 4) & vba2perl(item(I)) & "," Next I txt = txt _ & vbCrLf & Space(indent * 4 - 2) & "]" Case Else Debug.Print "No Handler for type: " & TypeName(item) End Select vba2perl = txt End Function