我有一个向集合添加用户窗体控件的循环。
由于在多个地方都需要这个集合,所以我将它推到一个模块中,并在需要时调用它。
这意味着集合只在需要时才在内存中,但这也意味着每次要使用它时都要运行一个循环。
我 * 本 * 可以给出集合模块级范围,并在第一次需要它时创建它。
我本来会运行一次循环,但是集合会一直保存在内存中。
我发现32位Excel的内存限制为1.75Gb(尽管这可以扩展,还有64位版本),VBA Excel是单线程的。
看起来我应该优先考虑处理器效率而不是内存效率,除非我有特殊的需要,这样不仅应用程序会更快,而且可能会更节能。
赋予收集模块级别的作用域会使其容易发生意外更改。
有没有办法创建一次集合,但不给予它模块级的作用域?
更好的是,有没有一种方法可以做到这一点,只有在需要的时候它才在内存中?
3条答案
按热度按时间33qvvth11#
我不认为有任何方法可以创建一个比模块小的函数作用域(这似乎是您想要的)。
如果你担心意外的修改,你可以创建一个类来实现一个只读数组。这个类的一个示例可以是模块级的,但是一旦设置了这些项,它们就既不能被修改,也不能被新值替换。
在类模块中:
测试代码(在标准代码模块中):
运行
test2
时,输出为:当然,你可以创建一个类的新示例并将其赋给
A
,对象是只读的,变量本身不是,这足以防止意外修改。上面的代码主要是概念验证。你可以改进它,例如,如果你传递给它的数据不是数组,它会抛出一个错误。你也可以抛出一个错误,而不是在试图更改数据时什么都不做,而不是简单地记录它。此外,您可能希望尝试使用this clever way来使
Item()
成为默认方法,以便可以只使用A(0)
而不是A.Item(0)
。laik7k3q2#
经过一段时间的调整,我想我已经找到了一个方法来做我想做的事情。虽然我不确定这是否是最好的方法...
以及按钮来测试它。
据我所知,只有当createColl为true时才创建集合,但是一旦创建了集合,它就像具有模块级作用域一样保留在内存中。
tktrz96b3#
我会告诉你我通常是怎么做的。首先我使用字典而不是集合,更加灵活。字典在用户窗体级别作用域是公共的,所以它可以从工作簿中的任何地方访问。如果控件需要为事件编码,我会抛出一个类。
因为我不喜欢按名称调用窗体,所以我有一个函数,它在所有加载的userforms中循环,并在vba.userforms集合中给我它的索引。
最后,我的字典可以这样命名:第一个月
可以使用ifdict.exists()方法检查控件是否已经在其中,而不需要循环遍历整个现有字典。