2010-10-05 7 views
5

J'utilise DoEvents pour forcer une mise à jour d'un indicateur de progression dans la barre d'état (ou dans une cellule de la feuille) comme dans l'exemple de code ci-dessous. Mais l'écran ne se rafraîchit pas, ou arrête de rafraîchir à un moment donné. La tâche se termine finalement mais la barre de progression est inutile.DoEvents ne fait pas les événements ... Pourquoi?

Pourquoi ne pas DoEvents "faire les événements"? Que puis-je faire pour forcer une mise à jour de l'écran?

Editer: J'utilise Excel 2003 sur Windows XP. Il s'agit d'un suivi d'un earlier question; Merci à Robert Mearns pour sa réponse et l'exemple de code ci-dessous.

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

Avez-vous essayé sans 'Application.ScreenUpdating = FALSE'? –

+0

Curieux ... il fonctionne bien (en ajoutant une boucle interne pour prendre un peu de temps) sur ma machine ... –

+0

Veuillez poster les versions Excel & OS –

Répondre

9

J'ai trouvé DoEvents n'est pas toujours complètement fiable. Je suggère d'essayer deux choses différentes. Commencez par placer l'appel DoEvents immédiatement après la mise à jour de la barre d'état (avant votre ligne Some code ....).

Si cela ne fonctionne pas, j'ai trouvé dans certains cas que l'utilisation de l'API Sleep est un moyen plus fiable de générer du temps processeur. C'est généralement la première chose que j'essaie si DoEvents ne fonctionne pas comme je le souhaite. Vous devrez ajouter la ligne suivante en haut de votre module (en dehors de votre fonction):

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

Ensuite, ajoutez cette ligne à la place, ou en plus, DoEvents:

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

Vous pouvez essayer d'augmenter la durée de pause du programme en utilisant le mode veille si 1 ms ne fonctionne pas.

1

J'ai trouvé qu'appeler DoEvents avant la mise à jour de la barre d'état, plutôt qu'après, donne plus de résultats prévisibles/souhaitables.

L'extrait de code ci-dessus serait de:

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