3

我来自 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 中创建与上述完全相同的结构(即 $hash)?如何遍历该结构并检索存储在键上的值?这种结构是否支持“存在”、“删除”、“添加”等方法?
4

2 回答 2

1

我不知道有内置机制可以满足您的要求。您必须创建一个“keyedArray”类来实现您想要的方法。弄清楚这一点会让你在 VBA 学习曲线上更上一层楼。

一个好的起点是http://www.cpearson.com/excel/classes.aspx

如果这对您没有帮助,请在评论中说出来 - 我可能有一段时间再整理一个简短的例子。

于 2013-02-25T09:07:47.683 回答
1

您可能有以下三种需求之一:

  1. Interactive Debug——然后在调试器中添加断点,使用vba中的Add Watch,迭代展开结构
  2. 将数据获取到文本文件以进行一些后期处理 - 尝试查找 xml 或 json 导出器
  3. 完全按照您显示的方式获取数据,例如使用 Safe 导入 Perl。- 那么你需要自己编写一个递归过程。

后者将非常困难,因为大多数 vba 结构(除非您自己制作)都有循环。(像孩子 => [ ... ],父母 => FIX)。

VBA Collections 没有给你足够的支持,所以 Dictionary 是你需要的。(记住工具->“Miscrosoft Scripting Runtime”的参考)

以下内容并不完美,但可能会给你一个开始

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
于 2013-02-25T10:12:34.770 回答