【发布时间】:2019-12-08 22:51:44
【问题描述】:
我正在从 Excel 电子表格中导出多个 INI 文件,其中一行表示一个 INI 文件,INI 部分和键是列。到目前为止,这工作得很好,除了似乎 VBA 正在传递字典 ByRef (?),但让我解释一下:
Excel 电子表格如下所示:
| section 1 | section 2 | section 3 | ...
| key1 | key2 | key3 | key4 | key3 | ...
name 1 | value | value | value | value | value | ...
name 2 | value | value | value | value | value | ...
...
我从电子表格中动态获取所有 INI 部分、键和值,这就是为什么我决定不构建类模块而是设置具有 3 个嵌套字典的字典结构,如下所示:
innerdict:保存一个部分的键/值对
middledict:保存部分名称和带有键/值对的内部字典
outerdict:保存行用 middledict 命名
下面的简化代码应该可以解释我的情况:
Set outerDict = New Scripting.Dictionary
Set middleDict = New Scripting.Dictionary
Set innerDict = New Scripting.Dictionary
For row = 3 to 10
For col = 1 to 5
key = Cells(a,b).Value
value = Cells(x,y).Value
innerdict.Add key, value
If nextSectionGroup Then
middledict.Add sectionName, innerdict
innerdict.RemoveAll
End If
Next col
outerdict.Add linename, middledict
middledict.RemoveAll
Next row
一句话:
从第一个值行开始,我遍历列,填充内部字典中的键/值对,直到我到达一个部分的末尾。
然后我(想要) 将innerdict 复制到middledict 中,然后删除innerdict 的内容,以便下一节使用。如果我打到整行的末尾,我将middledict 复制到outerdict 并删除middledict 的内容,以便它可以用于下一行。
但是运行上述代码后,middledict 和innerdict 无法通过outerdict 访问,看起来它们只是空的。如果我删除那些 .RemoveAll 语句,代码可以正常工作,但会用错误的内容填充字典。
在我看来,dict.Add 不会将内容复制到父 dict,而是进行引用。这可以解释为什么在.RemoveAll 之后内容为空。
但是如何解决呢,有人能指点一下吗?
谢谢。
【问题讨论】:
-
无论
ByVal还是ByRef,在赋值或作为参数传递时,引用类型的实例都不会被复制。类是引用类型。字典是一个类。 -
因为你想克隆一个字典,这是一个不受你控制的类,你需要手动克隆它(创建一个新字典并添加原始字典中的所有键和值) .请注意,这将创建一个浅拷贝,即字典将不同,但如果字典中包含的值本身是引用类型,则两个字典将引用相同的数据实例,您需要克隆他们也是。
-
将
.RemoveAll替换为Set ... = New Scripting.Dictionary以创建新引用。尽管您应该避免嵌套字典。例如,如果您的目标是按名称、部分、键获取值,则将所有值存储在一个字典中:dict.Add name & "|" & section & "|" & key, Value -
当然,无论您是否销毁对象都会有所不同。问题是,无论哪种方式,你都是not destroying them。
middledict保留对您所有innerdicts 的引用,否则您以后如何检索它们?
标签: excel vba dictionary nested