DoEvents不执行事件,为什么?

6
我正在使用DoEvents来强制更新进度指示器,它位于状态栏(或工作表中的某个单元格)中,就像下面的示例代码一样。但屏幕没有刷新,或在某个点停止刷新。任务最终完成,但进度条无用。
为什么DoEvents不会"执行事件"? 我还能做什么来强制更新屏幕?
编辑:我在Windows XP上使用Excel 2003。
这是对之前的问题的跟进;感谢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

5
你尝试过不使用 Application.ScreenUpdating = False 吗? - Peter Lang
好奇心驱使我在我的电脑上运行了一下(添加一个内部循环来占用一些时间),结果运行良好。 - Dr. belisarius
请提供Excel和操作系统的版本。 - Dr. belisarius
2个回答

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毫秒无效,您可以尝试使用sleep增加程序暂停的时间长度。


1

我发现在更新状态栏之前调用 DoEvents 而不是之后,可以产生更可预测/更理想的结果。

以上代码片段如下:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接