我在项目中有一个大的用户窗体,当它加载到内存时会导致一些问题。 Userform_Initialize
事件中没有任何异国情况发生(仅填充组合框并设置默认属性)。
几周前,当用户形态不大(以KB为单位)时,一切都运行得很好。最初,我认为工作簿已损坏,并继续导出每个用户表单,模块和类,重新导入到新工作簿,然后编译项目,因为我总是这样做。这并没有解决问题。有趣的是,当我在初始化事件的顶部放置Stop
并逐步执行代码时,一切正常。
主要想法
这让我想到问题的可能原因是userform非常大,因此将用户表单加载到内存中的过程比典型加载花费的时间更长。本质上,vb编辑器继续执行initialize事件中的代码,试图访问可能尚未在内存中的控件。
我做了一些粗略的分析,以便很好地了解有问题的用户形态有多大。导出用户窗体并将其重新导入到空白工作簿中。没有用户表单的工作簿大约是30 KB
,使用userform,工作簿已超过350 KB
,因此我们可以得出结论,用户表单大约是320 KB
。
重要的是要注意我在我的项目中有大量的错误处理,但是,我无法识别这个特定错误,因为它发生在initialize事件中(错误处理在这个特定事件中是不可能的[Bovey] ,Professional Excel Development,pg 489])。
问题:除了时间延迟(例如,通过Windows API Application.Wait
或Sleep
),还有其他方法可以避免崩溃吗?
的更新
事实证明,延迟应用程序也无法可靠地工作。我实际上删除了整个Initialize事件也无济于事。我在原帖中忘记提及的一件事是,我在滥用Debug -->> Compile VBA Project
功能。请参阅下面的答案。
答案 0 :(得分:1)
在处理了这段时间之后,我的一位同事简单地评论了一行随机代码(不在UserForm_Initialize
,只是在一些随机模块中),保存了文件,并重新打开了它,没有任何问题。然后我们发现问题不在代码中,而在于Debug -->> Compile VBA Project
。在大多数情况下,我使用Debug -->> Compile VBA Project
,大约每小时一次,因为我正在编码。然后我保存该文件并继续在同一个编译文件上进行开发。如果说完了,我可能会在两周内运行Debug -->> Compile VBA Project
约100次。然后我在this website上发现了Chip Pearson的评论:
永远不会将VBA代码存储为您键入的纯文本 编辑。输入立即转换为平台和 与版本无关的字节代码,称为OpCodes。这些操作码是 由编辑器转换为您在屏幕上看到的文本。当你 编译项目,编译器将这些OpCode转换为 特定于平台和版本的代码,称为ExCodes。当你运行 代码,运行时读取ExCodes并执行实际的机器代码 代表基于ExCodes的项目。整个过程是 原则上类似于Java和Java虚拟机的工作方式。
如果要将所有VBA代码导出到文本文件,然后删除 所有模块然后重新导入文本文件中的代码 进入VBA(这正是Rob Bovey的Code Cleaner所做的),你将会 看文件大小减少了。这是因为ExCodes被清除了 并且尚未重新创建。然后,如果你编译项目,那么 文件大小会增加,因为它现在还存储了ExCodes 到OpCodes。
你真的不需要编译代码。 VBA会自动完成 它在必要时。但是,Compile命令也会执行语法 检查,这是它唯一真正的实际目的。
这是来自Rob Bovey自己找到here(你也会在该网站找到Rob Bovey的代码清洁工):
在创建VBA程序的过程中,会在文件中构建大量垃圾代码。如果您不定期清理文件,您将开始遇到由此额外行李引起的奇怪问题。清理项目涉及将其所有VBComponents的内容导出到文本文件,删除组件,然后从文本文件中导回组件。
然后我就像我在原始问题中所做的那样做了。我导出了所有模块,将它们重新导入到一个新的excel工作簿中,添加了相关的库,并且DID NOT(就像我之前一样)运行Debug -->> Compile VBA Project
。从那时起我就没有任何问题了。