2010-10-05 19 views
5

Sto utilizzando DoEvents per forzare un aggiornamento di un indicatore di stato nella barra di stato (o in alcune celle del foglio) come nel codice di esempio riportato di seguito. Ma lo schermo non si aggiorna, o smette di rinfrescare ad un certo punto. L'attività alla fine viene completata, ma la barra di avanzamento è inutile.DoEvents non fa gli eventi ... Perché?

Perché lo DoEvents non esegue gli eventi? Cos'altro posso fare per forzare un aggiornamento dello schermo?

Modifica: sto utilizzando Excel 2003 su Windows XP.

Questo è un seguito di uno earlier question; grazie a Robert Mearns per la sua risposta e il codice di esempio qui sotto.

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

Hai provato senza 'Application.ScreenUpdating = FALSE? –

+0

Curioso ... funziona correttamente (aggiungendo un ciclo interno per un po 'di tempo) sulla mia macchina ... –

+0

Per favore pubblica le versioni di Excel e OS –

risposta

9

Ho trovato DoEvents non è sempre completamente affidabile. Suggerirei di provare due cose diverse.

Innanzitutto, provare a effettuare la chiamata DoEvents subito dopo l'aggiornamento della barra di stato (ad esempio, prima della linea Some code ....).

Se ciò non funziona, in alcuni casi ho riscontrato che l'utilizzo dell'API Sleep è un modo più affidabile per ottenere il tempo del processore. Di solito è la prima cosa che provo se DoEvents non funziona come vorrei. Avrai bisogno di aggiungere la seguente riga nella parte superiore del modulo (al di fuori della vostra funzione):

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

Quindi aggiungere questa linea al posto di, o in aggiunta a, DoEvents:

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

Si potrebbe provare ad aumentare il periodo di tempo in cui si interrompe il programma usando sleep se 1 ms non funziona.

1

Ho scoperto che chiamare DoEvents prima di aggiornare la barra di stato, piuttosto che dopo, produce risultati più prevedibili/desiderabili.

Il frammento di codice da sopra sarebbe:

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