DoEvents не делает события ... Почему? - PullRequest
6 голосов
/ 05 октября 2010

Я использую DoEvents для принудительного обновления индикатора прогресса в строке состояния (или в некоторой ячейке на листе), как в примере кода ниже. Но экран не обновляется или перестает обновляться в какой-то момент. Задача в конечном итоге завершается, но индикатор выполнения бесполезен.

Почему бы DoEvents не "сделать события"? Что еще можно сделать для принудительного обновления экрана?

Редактировать: я использую Excel 2003 в Windows XP.

Это ответ на предыдущий вопрос ; спасибо Роберту Мернсу за его ответ и пример кода ниже.

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 ]

10 голосов
/ 08 октября 2010

Я обнаружил, что 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 мс.

1 голос
/ 14 февраля 2012

Я обнаружил, что вызов DoEvents до обновления строки состояния, а не после, дает более предсказуемые / желательные результаты.

Фрагмент кода сверху будет выглядеть так:

    fractionDone = CDbl(i) / CDbl(iMax)
    DoEvents
    Application.StatusBar = Format(fractionDone, "0%") & " done..."
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...