2010-10-05 18 views
5

Estoy usando DoEvents para forzar una actualización de un indicador de progreso en la barra de estado (o en alguna celda de la hoja) como en el siguiente código de ejemplo. Pero la pantalla no se actualiza o deja de refrescarse en algún momento. La tarea finalmente se completa, pero la barra de progreso es inútil.DoEvents no hace los eventos ... ¿Por qué?

Por qué no DoEvents "hará los eventos"? ¿Qué más puedo hacer para forzar una actualización de pantalla?

Editar: Estoy usando Excel 2003 en Windows XP.

Esta es una continuación de un earlier question; Gracias a Robert Mearns por su respuesta y el código de muestra a continuación.

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

¿Ha intentado sin 'Application.ScreenUpdating = false'? –

+0

Curioso ... funciona bien (agregando un bucle interno para tomarse un tiempo) en mi máquina ... –

+0

Publique las versiones de Excel y SO –

Respuesta

9

He encontrado que DoEvents no siempre es completamente confiable. Sugeriría probar dos cosas diferentes.

En primer lugar, intente colocar los DoEvents llaman inmediatamente después de la actualización de la barra de estado (es decir, antes de que su línea de Some code ....).

Si eso no funciona, he encontrado en algunos casos que el uso de la API del sueño es una forma más fiable para obtener el tiempo de procesador. Por lo general, lo primero que intento es si DoEvents no funciona como me gustaría. Usted tendrá que añadir la siguiente línea en la parte superior de su módulo (fuera de su función):

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

A continuación, agregue esta línea en lugar de, o además de, DoEvents:

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

Puede intentar aumentar el tiempo de pausa del programa utilizando el modo reposo si 1 ms no funciona.

1

he encontrado que llamar a DoEvents antes de actualizar la barra de estado, en lugar de después, produce resultados más predecibles/deseables.

El fragmento de código de arriba sería:

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