【问题标题】:Is it possible to create, and set VBA Dictionaries outside of a Function(s)?是否可以在函数之外创建和设置 VBA 字典?
【发布时间】:2019-05-10 20:01:50
【问题描述】:

我在 Excel VBA 中创建了几个需要使用 3 个字典的自定义函数。

这些字典一旦设置就不会改变。

现在每个字典都是在每个函数中创建的。

我宁愿清理它,设置一次字典,然后在函数中引用它。

很遗憾,我似乎找不到任何关于此主题的文档。

【问题讨论】:

  • 您可以创建一个可以从任何模块或对象访问的全局变量。或者,您可以创建一个保存字典的持久对象类(并可能提供更好的接口)。
  • 虽然这似乎是一个令人信服的想法,但您很可能不需要任何全局字典对象。全局状态为不可维护的代码铺平了道路。全局对象的引用可以是Set,可以在任何地方使用任何代码。根据您需要它的用途(信息太少无法说明),将状态封装在一个对象中,并将该对象作为参数传递给需要它的函数,这绝对是一个更好的主意。这些函数是完全独立的还是在同一个调用图中?
  • 使用 ADODB 代替字典。它们可以通过一个函数调用保存到磁盘。请参阅此处的示例 winsourcecode.blogspot.com/2019/05/…docs.microsoft.com/en-us/sql/ado/reference/ado-api/… 的文档
  • @Noodles 对 OP 需要全局字典的用途做出了相当疯狂的假设。
  • @Noddles 我正在使用字典来利用 .Exists 方法。

标签: excel vba excel-formula excel-2016


【解决方案1】:

您正在寻找全局变量,它们是在程序的所有执行过程中在内存中存活的变量。

实际上:

Dim myDictionary As Scripting.Dictionary '<-- on top of module, outside of any macro/function. This makes the variable LOCAL to the module (i.e. accessible all over the subs and functions of the module)
'Alternatively (one or the other)
Public myDictionary As Scripting.Dictionary '<-- the variable is GLOBAL to all the program.

Sub init() '<-- initialize your dictionary once
    Set myDictionary = New Scripting.Dictionary
    myDictionary.add "Apples", 50
    myDictionary.add "Bananas", 40
End Sub

Function a() As Integer
    ...
    a = myDictionary("Apples") '<-- use your dictionary when you want
    ...
End Function

您可以在ThisWorkbook.Open 事件中调用init,这样一旦您的工作簿打开,您的字典就会在整个执行过程中存在。

【讨论】:

  • 除了Dim 始终是本地/私有的。全局变量是Public
  • @MathieuGuindon Dim 适用于您声明它们的模块,Global 适用于所有模块。我错了吗?认为你不应该教他使用全局变量,而是将参数传递给函数 Matteo。
  • @MathieuGuindon 对于Dim 和您在问题下写的评论都是正确的。将在答案中指定。
  • 完全同意(请参阅我自己关于 OP 下的全局状态的评论)——除了这里的两个答案都在谈论“全局变量”,并且没有一个实际上包含任何全局变量,这......感觉很奇怪。
  • @Damian,虽然我通常倾向于同意你的观点,并且我们应该尽可能避免使用全局变量,但这里似乎 OP 想要创建一种Const。这是由其他语言提供的(例如,在 Java 中你会说 static),但 VBA 不允许 Const 类型为 Dictionary。我想说的是一种解决方法,我会尽量避免它,但有时我们真的不能做太大的不同。
【解决方案2】:

类似这样的:

'declare some global variables to hold your dictionaries
Dim dict1 as object, dict2 as object, dict3 as object

'a sub to create and populate the dictionaries
sub InitDicts()
    If dict1 is nothing then

        'create and populate dicts 1-3

    End if
end sub

'*** functions which use the dictionaries ***

Function ThisFunction()
    InitDicts
    'use dicts
end function

Function ThatFunction()
    InitDicts
    'use dicts
end function

【讨论】:

  • Dim 始终是本地/私有的。全局变量是Public
  • 当我在每个函数中 InitDict 时,我得到一个编译错误:未定义子或函数。
  • 您是否创建了子,是调用InitDict,还是InitDicts
  • @MathieuGuindon - 我应该说“模块级变量”
  • 对不起,我是一个迂腐的烦恼;-)
猜你喜欢
  • 1970-01-01
  • 2020-06-20
  • 2011-11-09
  • 1970-01-01
  • 2016-08-14
  • 2011-07-05
  • 2016-04-04
  • 2013-04-14
  • 2018-11-09
相关资源
最近更新 更多