大家。我在Excel工作簿中有一个大型VBA模块,它从一堆其他远程工作簿中获取数据并将其复制到当前工作簿中。然后,它格式化并分析数据。所有这一切都运行正常,但可能需要一段时间,因为我在两个工作表中处理超过30,000行数据(并且每天都在增长)。
所以,我试图让它将进度作为百分比放在" Admin"工作表。这似乎也行,但有时候也行。在执行期间,Excel(看似随意)跳过更新进度的.Value
行代码。有时,它会在大约四分之三的时间内更新,有时,它根本不会更新,直到执行结束。有谁知道为什么?以下是相关代码的摘要。
<some code that declares variables and whatnot>
ThisWorkbook.Worksheets("Admin").Range("H18").Value = "Waiting..."
For Each rw In rng.Rows
<code that does the data-gathering and analysis>
progress = <code that returns a Double value>
ThisWorkbook.Worksheets("Admin").Range("H18").Value = progress & "% complete."
Next rw
ThisWorkbook.Worksheets("Admin").Range("H18").Value = "Done!"
<some cleanup code>
有时,&#34;等待......&#34;永远不会显示。其他时候,它是。 &#34;完成&#34!;几乎总是在执行结束时显示,但Admin!H18并没有针对很多很多循环进行更新,并且当它被跳过时它永远不会是同一组循环。计算仍在进行中(我认为),因为当它更新时,它会更新为正确的值。但是它并没有在每个循环中更新单元格,只是其中的一部分。
答案 0 :(得分:4)
更新单元格后添加DoEvents
可能会解决此问题。但是,如果禁用ScreenUpdating(这会阻止您的状态更新在工作表上更新),您的代码可能会运行得更快。请尝试更新状态栏。
此外 - 将您的状态更新拆分为单独的Sub将简化您的代码,并让您更轻松地更改显示更新的方式。
Sub DoStatus(m)
ThisWorkbook.Worksheets("Admin").Range("H18").Value = m
DoEvents
End Sub
答案 1 :(得分:2)
我相信如果您在设置其值后检查ThisWorkbook.Worksheets("Admin").Range("H18").Value
,则其值将完全符合预期。
虽然运行Application.ScreenUpdating=True
的VBA 通常在屏幕上显示代码正在执行的操作,但 no 要求Excel 必须更新屏幕。
相反,对于Application.ScreenUpdating=False
, 要求Excel 不得更新屏幕。
如果由于某种原因Excel无法命令更新屏幕所需的系统资源和执行Application.ScreenUpdating=True
时必须执行的其他任务,屏幕更新将暂时关闭,导致你描述的问题。 DoEvents
可能会解决这个问题,但如果您在工作簿中的其他位置发生了触发事件,则会导致性能下降和其他问题 - DoEvents
具体说明&#34;现在处理待处理事件&# 34。
如果您在代码运行时使用Application.ScreenUpdating=False
,并使用Application.StatusBar
显示状态,您将获得更好的性能。