DoEvents不做这些事件......为什么?

时间:2010-10-05 12:36:19

标签: vba excel-vba excel

我正在使用DoEvents强制更新状态栏(或表单中的某个单元格)中的进度指示器,如下面的示例代码所示。但屏幕不刷新,或在某些时候停止刷新。任务最终完成但进度条无用。

为什么不DoEvents“做事件”?我还可以做些什么来强制更新屏幕?

编辑:我在Windows XP上使用Excel 2003。

这是earlier question的后续行动;感谢Robert Mearns的答案以及下面的示例代码。

Sub ProgressMeter()

Dim booStatusBarState As Boolean
Dim iMax As Integer
Dim i As Integer

iMax = 100

    Application.ScreenUpdating = False
''//Turn off screen updating

    booStatusBarState = Application.DisplayStatusBar
''//Get the statusbar display setting

    Application.DisplayStatusBar = True
''//Make sure that the statusbar is visible

    For i = 1 To iMax ''// imax is usually 30 or so
        fractionDone = CDbl(i) / CDbl(iMax)
        Application.StatusBar = Format(fractionDone, "0%") & " done..."
        ''// or, alternatively:
        ''// statusRange.value = Format(fractionDone, "0%") & " done..."

        ''// Some code.......

        DoEvents
        ''//Yield Control

    Next i

    Application.DisplayStatusBar = booStatusBarState
''//Reset Status bar display setting

    Application.StatusBar = False
''//Return control of the Status bar to Excel

    Application.ScreenUpdating = True
''//Turn on screen updating

End Sub

2 个答案:

答案 0 :(得分:10)

我发现DoEvents并不总是完全可靠。我建议尝试两种不同的东西。

首先,尝试在状态栏更新后立即放置DoEvents调用(即在Some code ....行之前)。

如果这不起作用,我发现在某些情况下使用Sleep API是一种更可靠的方式来产生处理器时间。如果DoEvents不按照我的意愿工作,通常是我尝试的第一件事。您需要在模块顶部添加以下行(在函数外部):

    Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

然后添加此行代替DoEvents

    Sleep 1   'This will pause execution of your program for 1 ms

如果1 ms不起作用,您可以尝试增加使用sleep暂停程序的时间长度。

答案 1 :(得分:1)

我发现在更新状态栏之前调用DoEvents而不是之后会产生更多可预测/期望的结果。

上面的代码段是:

    fractionDone = CDbl(i) / CDbl(iMax)
    DoEvents
    Application.StatusBar = Format(fractionDone, "0%") & " done..."