如何在Excel VBA 2010中使用消息泵?

时间:2010-11-03 12:59:38

标签: excel vba excel-vba message-queue

我有一个需要很长时间的Excel宏。当我无人看管时,似乎崩溃了Excel(我在任务栏中收到了一条Not Responding消息),但是如果我设置一个每隔五或十秒就会被击中的断点,那就没关系了。麻烦的是,我需要从断点处继续大约25万次(我们正在寻找大约200个小时来执行这个野兽)

我猜测缺少消息泵活动会对内核产生影响,那么我如何刷新消息队列呢?或者我是否完全咆哮错误的树?

顺便说一句,我对此非常陌生,因此非常欢迎文档参考。

干杯, 盖

4 个答案:

答案 0 :(得分:7)

支持200h有点令人担忧的观点,但是您可以尝试{<3>}语句“放弃执行宏以便操作系统可以处理其他事件”。 (请注意,调用DoEvents会有额外的时间惩罚)

答案 1 :(得分:1)

我必须同意0xA3,如果你有一个预计需要超过200小时才能运行的excel例程,那么你要么以非常低效率的方式设置它,要么你是使用错误的工具完成这项工作。

无论如何,您可以采取一些措施来优化例行程序。如果您经常将值写入单个单元格,这些将特别有用。

Sub MarathonCalc

    Application.EnableEvents = False
    Application.ScreenUpdating = False

    ' Code to decode human genome goes here

    Application.EnableEvents = True
    Application.ScreenUpdating = True

End Sub

同样,如果您发布一些代码,我们可能会帮助您了解为什么这么长时间。

答案 2 :(得分:0)

“没有响应”并不意味着Excel崩溃,它只是意味着它实际上没有响应窗口消息。

除非这是一个问题,否则你无需担心。我很担心你的评论,你希望任务花费200小时(超过一周!)。在我看来,你没有使用正确的工具来完成这项工作。试着找出花了这么长时间,并解释你在做什么。然后我们可以看到如何更好地解决这个任务。

答案 3 :(得分:0)

之前的答案为您提供了'DoEvents',这是您问题的第一线修复。

然而......仔细观察发生的事情会引发一些令人担忧的问题。首先,Excel的线程模型相当原始:有一个进程(根据文档),并且没有内部或外部生成的事件,回调和消息创建新线程。一个进程,仅一个进程,其他所有内容都必须等到当前的VBA宏或电子表格计算运行完成。

实际上,有些事情可以打断这个:{esc}和{ctrl-break}(虽然这些可以暂时禁用),所以在Excel中至少有一个其他的线程在运行,并且你会对操作有所期望系统被允许进入一个过程...不是吗?

丑陋的现实是,在宏或计算运行时,Excel应用程序不允许外部事件和消息运行到“事件接收器”,除非您调用“DoEvents”和某些Windows消息(请注意大小写)不会被处理。

如果留下未记录数量的消息和外部事件,应用程序将崩溃。根据我自己的测试,我认为这个数字是50;有关于注册表设置的文档,但我没有链接到我认为不可靠的材料 - 我已经尝试了有问题的设置并发现它无效。

那么你离开了哪里?

首先,再看一下你的代码。 Application.EnableEvents = False和Application.ScreenUpdating = False是有用的设置:下一步是找到工作表上单个单元格的所有读写操作,只需抓取单元格数组 - 使用数组获取数组要快得多myVBAarray = Range.Value,在VBA中进行计算,并将VBA数组变量写回Range.Value。

其次......您还看到断点带来的“等待”状态允许某些事情自行解决。这听起来像异步运行的外部进程(数据库查询?):崩溃Excel的消息或事件是否来自这个过程?