web-dev-qa-db-fra.com

Effet de la mise à jour de l'écran

Je me suis amusé à mesurer les temps d'exécution du code pour évaluer les différences entre l'exécution de mes scripts localement et sur mon serveur. A un moment, j'ai oublié de désactiver screen updating et j'étais reconnaissant de ne pas être sensible aux lumières clignotantes avant d'y réfléchir plus en détail:

Quand j'ai commencé à utiliser VBA, j'ai toujours pensé que c'était utilisé pour que les utilisateurs finaux ne craignent pas de penser que leur ordinateur était sur le point de tomber en panne. Quand j'ai commencé à lire davantage sur l'amélioration de l'efficacité de votre code, j'ai compris à quoi il servait, mais quel effet screen updating a-t-il réellement sur le temps d'exécution de vos codes?

16
Alistair Weir

La désactivation de la mise à jour de l'écran ne modifiera le temps d'exécution que si le code interagit avec Excel de manière à modifier le contenu de l'écran. Plus la quantité d'écran change, plus l'impact sera important. Les autres réponses postées le démontrent bien. 

Les autres paramètres d'application pouvant influer sur le temps d'exécution sont le calcul et la gestion des événements. Utilisez ce modèle de code comme point de départ (le gestionnaire d'erreurs s'assure que ces propriétés sont réactivées à la fin du sous-répertoire, même en cas d'erreur).

Sub YourSub()
    On Error GoTo EH

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False

    ' Code here

CleanUp:
    On Error Resume Next
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
Exit Sub
EH:
    ' Do error handling
    GoTo CleanUp
End Sub

Il existe d'autres techniques pouvant améliorer encore plus la vitesse d'exécution.

Le plus utile incluent

  1. Évitez autant que possible Select, Activate et ActiveCell/Sheet/Workbook. À la place, déclarez et assignez des variables et référencez-les.
  2. Lors du référencement de plages étendues, copiez les données Range dans un tableau variant pour traitement et copiez le résultat dans la plage suivante.
  3. Utilisez Range.SpecialCells, Range.Find et Range.AutoFilter pour limiter le nombre de cellules référencées.

Il existe de nombreux exemples de ces techniques sur SO.

32
chris neilsen

Si vous souhaitez voir un exemple assez radical de pourquoi ScreenUpdating est important, exécutez le code suivant. Il me faut environ 45 fois plus de temps dans Excel 2011 pour exécuter ce swap sans ScreenUpdating = false! C'est une énorme différence dans le temps.

Sub testScreenUpdating()

    Dim i As Integer
    Dim numbSwitches As Integer
    Dim results As String

    'swap between sheets this number of times
    numbSwitches = 1000

    'keep track of time
    Dim startTime As Double
    startTime = Time

    'swap between sheets 1/2 (need both sheets or this will crash)
    For i = 1 To numbSwitches
        Sheets(1 + (i Mod 2)).Select
    Next i

    'get results
    results = "Screen Updating not disabled: " & Format(Time - startTime, "hh:mm:ss") & " seconds"
    startTime = Time

    'scenario 2 - screenupdating disabled

    Application.ScreenUpdating = False

    'swap between sheets 1/2 (need both sheets or this will crash)
    For i = 1 To numbSwitches
        Sheets(1 + (i Mod 2)).Select
    Next i

    Application.ScreenUpdating = True

    'get results for part two
    results = results & vbCrLf & "Screen Updating IS disabled: " & Format(Time - startTime, "hh:mm:ss") & " seconds"

    'show results
    MsgBox results


End Sub

En outre, même si nous parlons de moyens d'accroître l'efficacité, un autre point clé est que Select, Selection et Activate sont rarement (si jamais) nécessaires. Lorsque vous enregistrez des macros, elles seront toujours utilisées, mais il existe très peu de situations dans lesquelles vous devez réellement les utiliser dans du code. De même, tout ce qui contient Active dans le titre (tel que ActiveCell) indique normalement que vous aurez un code plus lent parce que vous sélectionnez probablement des cellules.

Vous pouvez presque toujours faire spécifiquement référence aux cellules/feuilles de calcul et éviter de sélectionner. Par exemple:

msgbox (Worksheets(1).Range("A1").value) 

fonctionnera que vous soyez ou non sur la première feuille de calcul. Une nouvelle erreur commune de VBA est de faire quelque chose de plus semblable à:

Worksheets(1).Select
msgbox (Range("A1").value)

ce qui est une étape inutile.

Cela ajoute beaucoup de temps au code d'exécution.

6
enderland

Premièrement, j'utilise le script écrit par Richie (Royaume-Uni) Post # 7 Here

Il itère simplement à travers une boucle en changeant la valeur de i dans une cellule. Je l'ai légèrement modifié pour qu'il se répète 10 000 fois et que je l'exécute 10 fois pour la taille de l'échantillon.

Quel est l'effet de la mise à jour de l'écran sur la vitesse d'exécution de mes codes?

Voici les durées d'exécution lorsque Screen Updating était désactivé et activé:

Disabled    Enabled
0.61909653  2.105066913
0.619555829 2.106865363
0.620805767 2.106866315
0.625528325 2.102403315
0.625319976 2.0991179
0.621287448 2.105103142
0.621540236 2.101392665
0.624537531 2.106866716
0.620401789 2.109004449

Comme vous pouvez le constater, l’exécution du code prend presque 3,5 fois plus de temps lorsque Screen Updating n’est pas désactivé. 

Ces deux codes ont été remplacés à l’aide du bouton Exécuter de l’éditeur VB, par opposition à la surveillance du tableur.

2 simples lignes au début et à la fin de votre code:

Application.ScreenUpdating = False
Application.ScreenUpdating = True

Mais, ils peuvent avoir un effet important sur l'efficacité de votre exécution!

Note: Évidemment, les avantages de Screen Updating seront bien connus par beaucoup ici, mais cela peut être avantageux pour les débutants et je trouve intéressant de voir les chiffres!

3
Alistair Weir

Je sais que c'est un vieux fil, mais:

  1. Définissez ScreenUpdating = true, mais n'oubliez pas de rétablir son ancienne valeur.
  2. Le changement de classeurs réinitialisera également ScreenUpdating.
1
Frank

Il y a une chose importante à savoir sur la mise à jour de l'écran que je n'ai vue dans aucune réponse précédente. Mon propre test m'a montré que l'activation et la désactivation de la mise à jour de l'écran prend environ 15 ms (testé en C # via Excel Interop). Gardez cela à l'esprit si vous voulez exécuter quelque chose qui prendrait moins de temps. Et après tout, n’activez/désactivez pas la mise à jour de l’écran de façon répétée. Ce serait un vrai tueur de performance.

Et encore une note (que vous ne voudrez probablement pas entendre) si vous voulez utiliser rapidement le C++. Il est généralement 5 à 10 fois plus rapide que VBA (ne me surprenez pas, cela dépend de ce que vous faites vraiment).

0
Sekory