DoEvents не делает события ... Почему?

я использую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
 Dr. belisarius05 окт. 2010 г., 15:35
Пожалуйста, опубликуйте версии для Excel и OS
 Dr. belisarius05 окт. 2010 г., 15:21
Любопытно ... он работает нормально (добавив внутренний цикл на некоторое время) на моей машине ...
 Peter Lang05 окт. 2010 г., 14:40
Вы пробовали безApplication.ScreenUpdating = False?

Ответы на вопрос(2)

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

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

    fractionDone = CDbl(i) / CDbl(iMax)
    DoEvents
    Application.StatusBar = Format(fractionDone, "0%") & " done..."
Решение Вопроса

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

Ваш ответ на вопрос