Question 138

Comment l'utilisateur peut-il interrompre un traitement très long ?

Il est parfois nécessaire de permettre à l'utilisateur d'interrompre un traitement long. Par exemple : de longs calculs, une procédure de traitements sur un grand nombre de fichiers, etc.
On veut aussi parfois interrompre le traitement tout simplement pour permettre le rafraichissement d'un élément grpahique, mettre à jour une barre de progression ou tout autre moyen d'indiquer la progreesion de l'action en cours.
Dans certains cas, le traitement n'a de sens que si il se termine entièrement (par exemple un tri) mais il y a aussi des traitements très longs qui peuvent être exécutés par partie (par exemple un traitement sur un ensemble de documents).
Dans le dernier cas, on peut interrompre le traitement à tout moment, pour éventuellement le reprendre la ou il en était resté.

Visual Basic étant un langage de programmation événementielle, il n'est pas évident d'interrompre un traitement pendant son exécution. On peut néanmoins avec quelques astuces implémenter ce type de mécanismes.

Le plus simple est de tester un évènement externe (l'appui sur un bouton par exemple) et de tester régulièrement (dans une des boucles du traitement long) si cet événement s'est produit. Dans l'affirmative, on peut alors effectuer l'action souhaitée.

Tout ceci repose sur l'utilisation de 2 idées :

  • Récupération l'événement externe (au moyen d'une variable de portée suffisante ou de tout autre moyen approprié)
  • Utilisation de la commande DoEvents qui permet de "donner la main" au système d'exploitation afin de lui permettre de continuer à gérer les événements externes.
L'exemple suivant, volontairement très simple, illustre ce principe.
Soit un traitement long, déclenché par un click sur le bouton Command1 (Démarrer). Le bouton Command2 (Interrompre) permet à l'utilisateur d'interrompre le traitement. Une confirmation est alors demandée depuis le traitement long, permettant de stopper ou de reprendre le traitement.

La variable (visible au niveau form) G_ASK_BREAK est utilisée pour détecter l'action "Appui sur Interrompre"
La commande DoEvents placée au niveau de la boucle la plus imbriquée permet au système de traiter l'appui sur le bouton de commande.

Option Explicit

Dim G_ASK_BREAK As Boolean

Private Sub Command1_Click()

    Dim i As Long, j As Long, k As Long
    Dim vRet As VbMsgBoxResult
    Dim must_break As Boolean

    G_ASK_BREAK = False
    For i = 1 To 10
        Label1.Caption = i
        For j = 1 To 100
            Label2.Caption = j
            For k = 1 To 100
                Label3.Caption = k
                DoEvents
                If G_ASK_BREAK Then
                    G_ASK_BREAK = False
                    vRet = MsgBox("Quitter?", vbYesNo)
                    If vRet = vbYes Then
                        must_break = True: Exit For
                    End If
                End If
            Next k
            If must_break Then Exit For
        Next j
        If must_break Then Exit For
    Next i
    If must_break Then
        MsgBox "traitement interrompu par l'utilisateur"
    Else
        MsgBox "traitement terminé"
    End If
End Sub

Private Sub Command2_Click()
    G_ASK_BREAK = True
End Sub

Private Sub Form_Load()
    Command1.Caption = "Démarrer"
    Command2.Caption = "Interrompre"
End Sub

Date de publication : 19 novembre 2006
Dernière modification : 19 novembre 2006
Rubriques : Divers
Mots-clés : interruption,DoEvents,traitement,rupture,événements