vba DoEvents 不做事件......为什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3863641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 10:50:40  来源:igfitidea点击:

DoEvents doesn't do the events... Why?

vbaexcel-vbaexcel

提问by Jean-Fran?ois Corbett

I'm using DoEventsto force an update of a progress indicator in the status bar (or in some cell in the sheet) as in the example code below. But the screen doesn't refresh, or stops refreshing at some point. The task eventually completes but the progress bar is useless.

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

Why won't DoEvents"do the events"? What else can I do to force a screen update?

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

Edit: I'm using Excel 2003 on Windows XP.

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

This is a follow up to an earlier question; thanks to Robert Mearnsfor his answer and the sample code below.

这是对先前问题的跟进;感谢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

回答by mwolfe02

I've found DoEvents is not always completely reliable. I would suggest trying two different things.

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

First, try placing the DoEvents call immediately after the Status Bar update (ie, before your Some code ....line).

首先,尝试在状态栏更新之后(即在您的Some code ....线路之前)立即调用 DoEvents 。

If that does not work, I've found in some cases that using the Sleep API is a more reliable way to yield processor time. It's usually the first thing I try if DoEvents is not working as I'd like. You'll need to add the following line at the top of your module (outside of your function):

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

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

Then add this line in place of, or in addition to, DoEvents:

然后添加此行来代替或补充DoEvents

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

You might try increasing the length of time you pause the program using sleep if 1 ms doesn't work.

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

回答by Yaacov

I've found that calling DoEvents before updating the status bar, rather than after, yields more predictable/desirable results.

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

The code snippet from above would be:

上面的代码片段将是:

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