écran d'attente sur code long en vb excel

écran d'attente sur code long en vb excel - VB/VBA/VBS - Programmation

Marsh Posté le 30-06-2004 à 15:27:21    

Bonjour à tous,
 
Je suis un peu coincé sur du code sous VB EXCEL  :??:  !
J'exécute des boucles relativement longues qui remplissent un tableau bidimensionnel, par extraction de données d'un fichier texte (plusieurs milliers de lignes).
Je souhaiterais pouvoir inscrire, pendant que mon code s'exécute en fond, un message demandant aux utilisateurs de patienter.
Je me suis cassé les dents sur la procédure splash-screen qui créée une tempo à l'ouverture. Pour ma part, je souhaiter que ma fenêtre d'attente reste ouverte devant ma feuille (sans la fermer, pour voir le déroulement des opérations) et qu'elle ne se ferme qu'à la fin de mes boucles.
Je n'y parviens pas, quelqu'un peut-il m'apporter son assistance car j'avoue que là je sèche   :pt1cable: !
 
Merci d'avance de votre aide, Gaston53  ;)

Reply

Marsh Posté le 30-06-2004 à 15:27:21   

Reply

Marsh Posté le 30-06-2004 à 16:18:48    

Ben c'est simple: juste avant de lancer tes boucles, tu load une form d'attente immediatement suivie de DoEvents:
frmWait.Show
DoEvents
et quand le travail est fini, tu decharge la form
Unload frmWait
DoEvents
 

Reply

Marsh Posté le 30-06-2004 à 16:23:42    

Avant le traîtement :
 
    UserForm1.ProgressBar1.Min = 0
    UserForm1.ProgressBar1.Max = nbRows
    UserForm1.ProgressBar1.Value = 0
    UserForm1.Label2.Caption = "0 %"
    UserForm1.Show
 
Pendant le traîtement :
 
        If Not UserForm1.Visible Then
            UserForm1.Show
        End If
        UserForm1.ProgressBar1.Min = 0
        UserForm1.ProgressBar1.Max = nbRows
        UserForm1.ProgressBar1.Value = j
        UserForm1.Label2.Caption = CStr(Format((j / nbRows) * 100, "##0.0" )) & " %"
 
Après le traîtement :
 
    UserForm1.Hide
    Sheets(2).Activate
 
Et tu fais une form :
 
http://perso.wanadoo.fr/magicbuzz/wait.jpg

Reply

Marsh Posté le 30-06-2004 à 18:55:30    

Pour info, voilà le code après essai :
Sauf erreur de compréhension (ou de saisie) de ma part,
il me réclame à chaque fois de fermer manuellement
la Form !
 
 
Private Sub Workbook_Open()
 
Load UserForm1
 
'Ben c'est simple: juste avant de lancer tes boucles,
'tu load une form d'attente immediatement suivie de
 
DoEvents
UserForm1.Show
DoEvents
 
x = 0
For x = 1 To 5000
Selection.Range("A" & x) = x
Next
 
'et quand le travail est fini, tu decharge la form
 
Unload UserForm1
DoEvents
 
 
End Sub
 
 

JiHemAir a écrit :

Ben c'est simple: juste avant de lancer tes boucles, tu load une form d'attente immediatement suivie de DoEvents:
frmWait.Show
DoEvents
et quand le travail est fini, tu decharge la form
Unload frmWait
DoEvents

Reply

Marsh Posté le 30-06-2004 à 19:07:25    

Là, je crains modestement que mon petit niveau ne soit un peu
faible !
 
Ton code m'amène à poser plusieurs questions complémentaires :
- nbRows=nombre d'itérations de la boucle ?
- UserForm1.ProgressBar1.Value = j -> j=nbRows ?
- enfin le + dur pour moi, comment créé-t-on une telle Form ?
(oups!! autant pour moi, j'ai trouvé le contrôle a rajouter !)
 
 
 

Arjuna a écrit :

Avant le traîtement :
 
    UserForm1.ProgressBar1.Min = 0
    UserForm1.ProgressBar1.Max = nbRows
    UserForm1.ProgressBar1.Value = 0
    UserForm1.Label2.Caption = "0 %"
    UserForm1.Show
 
Pendant le traîtement :
 
        If Not UserForm1.Visible Then
            UserForm1.Show
        End If
        UserForm1.ProgressBar1.Min = 0
        UserForm1.ProgressBar1.Max = nbRows
        UserForm1.ProgressBar1.Value = j
        UserForm1.Label2.Caption = CStr(Format((j / nbRows) * 100, "##0.0" )) & " %"
 
Après le traîtement :
 
    UserForm1.Hide
    Sheets(2).Activate
 
Et tu fais une form :
 
http://perso.wanadoo.fr/magicbuzz/wait.jpg


Message édité par gaston53 le 30-06-2004 à 19:16:17
Reply

Marsh Posté le 30-06-2004 à 21:02:49    

- nbRows est en effet le nombre d'itération de la boucle (si ton traîtement est une boucle). Si tu ne connais pas ce nombre, alors oublie la progressbar.
 
- j n'est pasq nbRows, mais un compteur qui indique à quelle itération tu es dans la boucle. Dans mon cas, il s'agit d'un for, donc j'utilise mon ompteur "j"
 
- Pour le dernier point tu as à priori trouvé tout seul ;)

Reply

Marsh Posté le 30-06-2004 à 23:09:41    

Bonsoir,
 
Voici le code ci-dessous que j'ai saisi grâce à tes
indications.
Hélas, j'ai toujours le même problème, il faut
cliquer sur le "X" de fermeture de la fenêtre Form
à chaque itération pour continuer !
 
Private Sub Workbook_Open()
 
'Avant le traîtement :
 
    UserForm1.ProgressBar1.Min = 0
    UserForm1.ProgressBar1.Max = 5000
    UserForm1.ProgressBar1.Value = 0
    UserForm1.Label1.Caption = "0 %"
    UserForm1.Show
     
 
'Pendant le traîtement :
 
x = 0
For x = 1 To 5000
Selection.Range("A" & x) = x
 
        If Not UserForm1.Visible Then
            UserForm1.Show
        End If
        UserForm1.ProgressBar1.Min = 0
        UserForm1.ProgressBar1.Max = 5000
        UserForm1.ProgressBar1.Value = x
        UserForm1.Label1.Caption = CStr(Format((x / 5000) * 100, "##0.0" )) & " %"
Next
 
'Après le traîtement :
 
    UserForm1.Hide
    Sheets(2).Activate
 
 
End Sub
 
 

Arjuna a écrit :

- nbRows est en effet le nombre d'itération de la boucle (si ton traîtement est une boucle). Si tu ne connais pas ce nombre, alors oublie la progressbar.
 
- j n'est pasq nbRows, mais un compteur qui indique à quelle itération tu es dans la boucle. Dans mon cas, il s'agit d'un for, donc j'utilise mon ompteur "j"
 
- Pour le dernier point tu as à priori trouvé tout seul ;)

Reply

Marsh Posté le 01-07-2004 à 01:19:41    

Etrange... Je regarderai ça demain au taff, là j'ai pas ma macro sous les yeux... Pourtant, avec le Hide à la fin, elle devraut au moins disparaître de l'écran...
 
A tout hasard, remplace le Shets(2).Active par Sheets(1).Activate, mais je doute que ça change quoi que ce soit...
 
Quelle version d'Excel ?

Reply

Marsh Posté le 01-07-2004 à 09:16:28    

C'est bizarre ton truc.
Ci-dessous le code complet de ma macro :
 


Const offSet = 5
Const READYSTATE_COMPLETE = 4
 
Private Sub CommandButton1_Click()
    Dim i As Integer
    Dim query As String
    Dim inet As Object
    Dim reponse As String
    Dim erros As Integer
    Dim nbRows As Integer
     
    Set inet = CreateObject("InternetExplorer.Application" )
     
    i = offSet
    nbRows = 0
    errors = 0
    Do While True
        If Sheets(1).Cells(i, 1) = "" Then
            Exit Do
        Else
            nbRows = nbRows + 1
            i = i + 1
        End If
    Loop
 
    i = offSet
    UserForm1.ProgressBar1.Min = 0
    UserForm1.ProgressBar1.Max = nbRows
    UserForm1.ProgressBar1.Value = 0
    UserForm1.Label2.Caption = "0 %"
    UserForm1.Show
    For j = 1 To nbRows
        query = Sheets(1).Cells(i, 1) & "¤" & Sheets(1).Cells(i, 2) & "¤" & Sheets(1).Cells(i, 3) & "¤" & Sheets(1).Cells(i, 4) & "¤" & Sheets(1).Cells(i, 5) & "¤" & Sheets(1).Cells(i, 6) & "¤" & Sheets(1).Cells(i, 7) & "¤" & Sheets(1).Cells(i, 8) & "¤" & Sheets(1).Cells(i, 9)
         
        inet.Navigate ("http://gemseas.euro.med.ge.com/sales/crm/integration.asp?query=" & Replace(query, "&", "%26" ))
        Do While Not inet.ReadyState = READYSTATE_COMPLETE
            DoEvents
        Loop
     
        i = i + 1
        Sheets(2).Cells(i - offSet, 1) = inet.Document.all.response.innerHTML
        If Left(inet.Document.all.response.innerHTML, 6) = "Error:" Then
            errors = errors + 1
        End If
        If Not UserForm1.Visible Then
            UserForm1.Show
        End If
        UserForm1.ProgressBar1.Min = 0
        UserForm1.ProgressBar1.Max = nbRows
        UserForm1.ProgressBar1.Value = j
        UserForm1.Label2.Caption = CStr(Format((j / nbRows) * 100, "##0.0" )) & " %"
    Next
    UserForm1.Hide
    Sheets(2).Activate
    MsgBox (i - offSet) & " lines exported with " & errors & " error(s)."
     
    inet.Quit
    Set inet = Nothing
End Sub


 
Pour résuler, sur la page 1, tu as un tableau dans lequel tu saisis des informations sur des campagnes promotionnelles. Généralement il y a quelques milliers de lignes (détail pour chaque triplet "client/produit/promo" ).
Ensuite, une boucle parse les lignes, et envoie une requête HTTP sur un serveur intranet afin d'insérer les lignes dans la base. La réponse est alors écrite dans la seconde feuille, afin d'avoir une trace.
 
Ma popup disparaît toute seule à la fin du traîtement :??:
 
Et j'ai bien vérifié, j'ai pas une ligne de code ailleur que dans cette page.

Reply

Marsh Posté le 01-07-2004 à 12:13:58    

Voilà, je pense, un code qui n'est pas parfait mais qui "tourne" apparemment correctement. Je l'ai repris et adapté en fonction :
 
1- de ton source qui laisse apparaître un DoEvents dans ta boucle et que j'ai ajouté ;
2- d'un constat qui m'est apparu en consultant l'aide contextuelle de VBA Excel et qui stipule que :
Un objet UserForm est toujours modal, il en résulte que l'utilisateur doit toujours répondre avant d'utiliser une autre partie de l'application. Aucun autre code ne s'exécutera tant que l'objet UserForm ne sera pas masqué ou déchargé. Bien que les autres feuilles de l'application soient désactivées pendant l'affichage d'un objet UserForm, les autres applications ne le sont pas.
 
Mes modifs sont, sauf erreur de manip, en rouge et les lignes de code qui peuvent être supprimées en vert (variables déjà initialisées ou initialisées implicitement par EXCEL) :
---------------------------------------------------------------------
Private Sub Workbook_Open()
 
'Avant le traîtement :
   
    UserForm1.ProgressBar1.Min = 0
    UserForm1.ProgressBar1.Max = 5000
    UserForm1.ProgressBar1.Value = 0
    UserForm1.Label1.Caption = "0,0 %"
    UserForm1.Show 0
   
'Pendant le traîtement :
   
x = 0
For x = 1 To 5000
Selection.Range("A" & x) = x
 
        DoEvents
        If Not UserForm1.Visible Then
            UserForm1.Show 0
        End If
        UserForm1.ProgressBar1.Min = 0
        UserForm1.ProgressBar1.Max = 5000
        UserForm1.ProgressBar1.Value = x
        UserForm1.Label1.Caption = CStr(Format((x / 5000) * 100, "##0,0" )) & " %"
Next
 
'Après le traîtement :
    UserForm1.Hide
    Sheets(1).Activate
 
End Sub
---------------------------------------------------------------------
Allez ... il me reste un dernier petit bug !!
Comment automatiser la confirmation systématique en ouverture de Workbook_Open visant à activer les macros ?
 
 

Arjuna a écrit :

Etrange... Je regarderai ça demain au taff, là j'ai pas ma macro sous les yeux... Pourtant, avec le Hide à la fin, elle devraut au moins disparaître de l'écran...
 
A tout hasard, remplace le Shets(2).Active par Sheets(1).Activate, mais je doute que ça change quoi que ce soit...
 
Quelle version d'Excel ?


Message édité par gaston53 le 02-07-2004 à 07:10:41
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed