【发布时间】:2020-03-20 08:44:52
【问题描述】:
彻底取消冗长的 API-Ridden 过程是地狱般的,我正在尝试找出最好的方式来驾驭地狱般的地狱。
我使用的是 excel 2016(手动计算且没有屏幕更新)- 我可能需要一些时间尝试在 2010 年运行该程序,看看未来几天是否有任何问题得到解决(我知道减速)。
随着时间的推移,我的程序LongProcedure 失去了成功使用其取消功能的能力(可能是由于复杂性增加)。它最初是不一致的,需要大量点击垃圾邮件才能取消,现在它完全失败了
设置如下:
首先,LongProcedure 位于类模块 LongClass 中,并检查了是否提前取消的公共属性,以便清理。
Public Sub LongProcedure()
' [Set up some things] '
For Each ' [Item In Some Large Collection (Est. 300 Items)] '
' [Some Code (ETA 5 Seconds) Sprinkled with 3-4 DoEvents] '
' [Export workbook (ETA 10 Seconds)] '
If (cancelLongProcedure) Then Exit For
Next
' [Clean up some things] '
GeneratorForm.Reset ' Let the UserForm know we're finished
End Sub
其次,我有一个从宏中显示的用户窗体,它实例化过程类并运行该过程。它包含一个运行按钮、一个状态标签和一个取消按钮。
Private MyLong As LongClass
Public Sub ButtonRunLongProcedure_Click()
Set myLong = New LongClass
myLong.LongProcedure()
End Sub
所以整体问题是双重的。ExportAsFixedFormat 调用会打开一个“正在发布...”进度条,它会将 excel 冻结大约十秒钟 - 很好。在我的所有努力中,我还没有找到一种在这种情况下处理用户输入的方法。
最重要的是,DoEvents 调用似乎不再执行任何操作来允许单击取消按钮。该过程不一致地冻结 excel、其他打开程序的选项卡,并且(当不冻结时)更新状态标签。
我试过了:
- 将 DoEvents 附加到
SetStatusLabel方法而不是喷洒 - 虽然表单仍然经常冻结,否则它会持续更新状态标签(但仍然不允许取消按钮) - 使用 winAPI
Sleep代替DoEvents,延迟时间为 1、5、10、50 和 250 毫秒 - 表单在没有 doevents 的情况下完全停止更新,并且两者都冻结得更多。 - 使用
Do While循环持续运行DoEvents一秒钟(冻结) - 重写 QueryClose 以取消表单。这个帮助很大。出于某种原因,可以比用户表单按钮更一致地单击关闭 [x] 按钮远 - 仍然不像我想要的那样一致。问题?在发布期间,Excel 停止响应,因此,如果您单击关闭按钮两次,现代 Windows 将结束该过程...而不进行清理。
- 使用 Application.OnTime 定期调用 DoEvents。整体情况似乎没有改善
- Alt-Tab 键。不完全是。出于某种原因,虽然 alt-tabbing 有时只会使用户窗体更难冻结,但有时它会使其停止冻结并更新。
这是一个我愿意做大量重构工作的问题,包括将长过程的想法分解为单独的方法、最初执行设置以及清理类终止。我正在寻找能够提供一致结果的东西。 - 我将接受从 excel 版本到 excel 设置到重构到 winAPI 调用的任何内容。
感谢您对此的任何见解。
【问题讨论】: