2010-09-17 35 views
20

Mi herramienta Excel realiza una tarea larga, y trato de ser amable con el usuario al proporcionar un informe de progreso en la barra de estado, o en alguna celda de la hoja, como se muestra a continuación . Pero la pantalla no se actualiza o deja de refrescarse en algún momento (por ejemplo, 33%). La tarea finalmente se completa, pero la barra de progreso es inútil.Forzar una actualización de pantalla en Excel VBA

¿Qué puedo hacer para forzar una actualización de pantalla?

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....... 

Next i 

estoy usando Excel 2003.

Respuesta

30

Agregue una función DoEvents dentro del lazo, consulte a continuación.

Es posible que también desee asegurarse de que la barra de estado esté visible para el usuario y restablecerla cuando se complete el código.

Sub ProgressMeter() 

Dim booStatusBarState As Boolean 
Dim iMax As Integer 
Dim i As Integer 

iMax = 10000 

    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 
+0

eso es un montón de 'doevents' si lo haces en cada ciclo, en cambio hazlo cada 10 aproximadamente:' si mod 10 = 0 entonces Doevents' –

6

Poner una llamada a DoEvents en el bucle.

Esto afectará el rendimiento, por lo que es posible que desee llamarlo solo en cada una, por ejemplo, décima iteración.
Sin embargo, si solo tiene 30, eso no es un problema.

0

Esto no está respondiendo directamente su pregunta en absoluto, sino simplemente brindando una alternativa. He encontrado en muchos cálculos largos de Excel que la mayoría de las veces esperar es tener valores de actualización de Excel en la pantalla. Si este es el caso, se podría insertar el siguiente código en la parte delantera de su substitución:

Application.ScreenUpdating = False 
Application.EnableEvents = False 

y poner esto como el final

Application.ScreenUpdating = True 
Application.EnableEvents = True 

he encontrado que esto acelera a menudo hasta que sea de código Estoy trabajando con tanto que es innecesario tener que alertar al usuario sobre el progreso. Es solo una idea para que pruebes, y su eficacia depende bastante de tu hoja y tus cálculos.

+0

buena información ... thx – ZEE

8

Los cuadros de texto en las hojas de trabajo a veces no se actualizan cuando se cambia el texto o el formato, e incluso el comando DoEvent no funciona.

Como no hay ningún comando en Excel para actualizar una hoja de cálculo en la forma en que se puede actualizar un formulario de usuario, es necesario utilizar un truco para obligar a Excel a actualizar la pantalla.

Los siguientes comandos parecen hacer el truco:

- ActiveSheet.Calculate  
- ActiveWindow.SmallScroll  
- Application.WindowState = Application.WindowState 
+0

Tuve ese problema con un formulario hoy. El formulario y la hoja dejaron de actualizarse. al agregar el truco application.windowstate cada pocas iteraciones resolví mi problema. –

+1

estaba trabajando para mí con el uso de 'ActiveWindow.SmallScroll down: = 1'' ActiveWindow.SmallScroll up: = 1' – Hubisan

0

En concreto, si se trata de un formulario de usuario, entonces es posible probar el métodorepintado. Puede encontrar un problema con DoEvents si está utilizando activadores de eventos en su formulario. Por ejemplo, cualquier tecla presionada mientras se ejecuta una función se enviará por DoEvents La entrada del teclado se procesará antes de actualizar la pantalla, por lo que si está cambiando celdas en una hoja de cálculo, mantenga presionada una de las teclas de flecha del teclado , entonces el evento de cambio de celda seguirá disparando antes de que termine la función principal.

Un UserForm no se actualizará en algunos casos, porque DoEvents activará los eventos; sin embargo, Repaint actualizará el UserForm y el usuario verá los cambios en la pantalla incluso cuando otro evento siga inmediatamente al evento anterior.

En el código de formulario de usuario es tan simple como:

Me.Repaint 
-3

Escribir DoEvents justo antes de la línea donde está actualizando la interfaz de usuario, que debería funcionar.

+5

¿Qué valor agrega esta respuesta a las otras que se escribieron hace 4-5 años? –