Amélioration code barre progression
Bonjour à toutes et tous,
Je me suis approprié le code du fichier ci joint (merci à son créateur dont j'ai bien entendu laissé les références et les remarques dans les commentaires du code) au sens ou j'ai essayé de l'adapter à mon besoin.
Ce code a pour objectif de faire patienter l'utilisateur en affichant une barre de progression en pourcentage au sein d'un userform lors de l'exécution d'une macro longue en temps de traitement, il est multi plateforme Mac et Windows.
2 Questions :
Quelles seraient vos remarque pour encore améliorer et optimiser ce code ?
Plus sur sa conception et sa rapidité que la partie "look" ou graphique (même si je suis preneur de toutes remarques)
Comment adapter ce code, pour une macro sans boucles mais dont les étapes successives serait des call vers plusieurs sous macros ?
J'imagine qu'il faudrait adapter la partie suivante du code de la Private Sub TestTheBar() du USERFORM ?
J'ai essayé mais je n'ai pas réussi à le faire, faire en sorte que chaque call incrémmente un compteur.
'Initilaizing Variables
lngNumberOfTasks = 100
'Calling the ShowProgress sub with ActionNumber = 0, to let the
'user know we are going to work on the 1st task.
Call modProgress.ShowProgress(0, lngNumberOfTasks, _
, False)
For lngCounter = 1 To lngNumberOfTasks
'The code for each task goes here
'<your code here>
'Call the ShowProgress sub each time a task is finished to
'the user know that X out of Y tasks are over, and that
'the X+1'th task is in progress.
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
Next lngCounterMerci
Cordialement
Hugues
HUGOBASS a écrit :Quelles seraient vos remarque pour encore améliorer et optimiser ce code ?
Plus sur sa conception et sa rapidité que la partie "look" ou graphique (même si je suis preneur de toutes remarques)
Comment adapter ce code, pour une macro sans boucles mais dont les étapes successives serait des call vers plusieurs sous macros ?
Suggestion = indique en dessous de la barre les différentes étapes en cours correspondant aux différents call que tu fais.
Bonjour le forum!
Idée qui vaut ce qu'elle vaut, si on part du principe que tous les "Call" sont de même durée, tu peux créer une variable que tu incrémentes à chaque appel et que tu divises par le nombre d'appel le tout multiplié par 100 pour avoir un "%age" de réalisation.
Sq'
Bonjour à tout le monde, Bonjour Steelson, Squalleh
Steelson :
Oui très bonne idée d'informer l'utilisateur par des labels sur le déroulement de la procédure sur le USERFORM
Merci
Squalleh :
Je te cite : "les "Call" sont de même durée, tu peux créer une variable que tu incrémentes à chaque appel et que tu divises par le nombre d'appel le tout multiplié par 100 pour avoir un "%age" de réalisation."
Merci
Même si les call ne sont pas de même durée je cherche effectivement à incrémenter un compteur pour affichage selon la méthode que tu me proposes (même si le % sera un peu indicatif).
Ce que je n'arrive pas à faire c'est la partie du code qui ferait que chaque call incrémenterait un compteur au lieu de la boucle de mon classeur exemple
For lngCounter = 1 To lngNumberOfTasks
'The code for each task goes here
'<your code here>
'Call the ShowProgress sub each time a task is finished to
'the user know that X out of Y tasks are over, and that
'the X+1'th task is in progress.
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
Next lngCounterMerci
Cordialement
Hugues
Bonjour,
Voici un code que j'ai créé et différent de celui que tu as posté !
Deux Labels sont utilisés mais pas sur un UserForm, directement sur la feuille nommée "Feuil1".
Trois procédures sont appelées l'une après l'autre et donc, la barre de progression va avancer par tranche de 30%
Supprime ces procédures et remplace par les tiennes.
Incrémente l'argument "PosAppel" par rapport à la procédure appelée (ici, de 1 à 3) et bien sûr, la variable Max doit aussi être adaptée (ici aussi, 3)
Dans un premier temps, colle le code dans un module standard, pose un bouton "Formulaire" et attache lui la procédure "ProgressBar" :
Sub ProgressBar()
Dim Fe As Worksheet
Dim Ctrl As OLEObject
Dim LblProgress As MSForms.Label
Dim LblFond As MSForms.Label
Dim LargeurLabel As Integer
Dim HauteurLabel As Integer
Dim Max As Long
Dim R As Single
Dim I As Long
Dim J As Long
Set Fe = Worksheets("Feuil1")
'défini les dimensions
LargeurLabel = 500
HauteurLabel = 20
With Fe
Application.ScreenUpdating = False
'suppression des labels parasites !
On Error Resume Next
.OLEObjects("LblProgress").Delete
.OLEObjects("LblFond").Delete
On Error GoTo 0
'crée le label servant de fond
Set Ctrl = .OLEObjects.Add("Forms.Label.1")
'passe l'objet à la variable afin d'utiliser les propriétés des labels
Set LblFond = Ctrl.Object
'défini certaines de ces dernières
With LblFond
.Name = "LblFond"
.Caption = ""
.BackColor = &HC0FFFF
.BorderStyle = fmBorderStyleSingle
.Left = Application.UsableWidth / 2 - LargeurLabel / 2
.Top = Application.UsableHeight / 2
.Width = LargeurLabel
.Height = HauteurLabel
End With
'crée le label servant de barre de progression
Set Ctrl = .OLEObjects.Add("Forms.Label.1")
'idem que plus haut
Set LblProgress = Ctrl.Object
With LblProgress
.Name = "LblProgress"
.Caption = ""
.BorderStyle = fmBorderStyleSingle
.BackColor = &H800000
.ForeColor = &HFFFFFF
.Left = Application.UsableWidth / 2 - LargeurLabel / 2
.Top = Application.UsableHeight / 2
.Width = 0
.Height = HauteurLabel
.TextAlign = fmTextAlignCenter
End With
Application.ScreenUpdating = True
'ici, commence la progression de la barre avec des appels successifs de procédures...
'################################################
Max = 3 '<-- pour le test, nombre de procédures appelées...
'rapport
R = LargeurLabel / Max
GestionProgress LblProgress, Max, R, "Macro1", 1
GestionProgress LblProgress, Max, R, "Macro2", 2
GestionProgress LblProgress, Max, R, "Macro3", 3
' GestionProgress LblProgress, Max, R, "Macro4", 4
' GestionProgress LblProgress, Max, R, "Macro5", 5
'################################################
'suppression des labels
On Error Resume Next
.OLEObjects("LblProgress").Delete
.OLEObjects("LblFond").Delete
End With
End Sub
Sub GestionProgress(LblProgress As MSForms.Label, MaxVal As Long, R As Single, Proc As String, PosAppel As Integer)
Application.Run Proc
LblProgress.Width = PosAppel * R
DoEvents
LblProgress.Caption = Format(PosAppel / MaxVal, "#0%")
End Sub
'PROCEDURES A SUPPRIMER ET A REMPLACER PAR LES TIENNES
Sub Macro1()
Dim I As Long
Dim ValeurMax As Long
ValeurMax = 100000
'boucle pour perdre du temps...
For I = 1 To ValeurMax
DoEvents
Next I
End Sub
Sub Macro2()
Dim I As Long
Dim ValeurMax As Long
ValeurMax = 100000
'boucle pour perdre du temps...
For I = 1 To ValeurMax
DoEvents
Next I
End Sub
Sub Macro3()
Dim I As Long
Dim ValeurMax As Long
ValeurMax = 100000
'boucle pour perdre du temps...
For I = 1 To ValeurMax
DoEvents
Next I
End SubBonjour Theze, Bonjour le Forum,
Theze merci pour ton partage de code.
Il fonctionne bien sous ma machine windows et la démarche est intéressante par contre il ne fonctionne pas sous ma machine MAC tant EXCEL OFFICE 365 (Excel 2015 mac) que Excel mac 2011; selon mes connaissance parce que la méthode OLEObjects et les contrôle ACTIVE X ne sont pas pris en charge dans les versions Excel pour MAC.
je cherche donc toujours un moyen d'adapter mon code qui lui fonctionne sous MAC, comment gérer le compteur sans boucle, faire que chaque CALL correspondent à une étape à compter.
Merci
Cordialement
Hugues
Reste à adapter ...
Bonjour Steelsonn, Bonjour Theze, Bonjour le forum
Theze, Steelson merci pour votre contribution active; vous m'avez tous les 2 mis sur le bon chemin.
Theze :
Malgré tout votre code ne fonctionne pas sous ma version Excel MAC.
Steelson :
Votre code que je vais personnaliser avec mes macros call fonctionne( (à noter que cela fonctionne avec Excel MAC 2015 office 365 mais pas avec Excel MAC 2011 qui ne gère pas si j'ai bien compris les USERFORM non modal), à partir du moment ou j'ai supprimé les parties du code qui désactive la croix rouge du USERFORM ci après non compatible avec excel MAC
Declare Function GetWindowLongA Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Declare Function SetWindowLongA Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
' Pour enlever la croix rouge et éviter toutes fermetures accidentelles
Sub UserForm_Initialize()
Dim hwnd As Long
hwnd = FindWindowA("Thunder" & IIf(Application.Version Like "8*", "X", "D") & "Frame", Me.Caption)
SetWindowLongA hwnd, -16, GetWindowLongA(hwnd, -16) And &HFFF7FFFF
End SubPar contre je vais effectivement désactiver l'action de la croix rouge (moins jolie que votre solution mais c'est la seule parade que j'ai trouvé pour rendre le code compatible tant excel windows que mac)
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then Cancel = True
End SubAutrement avec vos différentes pistes, j'ai aussi pu adapter le code initial de mon classeur exemple pour faire en sorte que chaque call vers mes procédures alimente le compteur de la barre de progression en dehors d'une boucle.
Je ne sais pas si c'est la manière la plus optimisée et rationnelle mais cela fonctionne.
Initilaizing Variables
lngNumberOfTasks = 10 'par exemple
'Calling the ShowProgress sub with ActionNumber = 0, to let the
'user know we are going to work on the 1st task.
Call modProgress.ShowProgress(0, lngNumberOfTasks, _
, False)
lngCounter = 1
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 1
lngCounter = 2
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 2
lngCounter = 3
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 3
lngCounter = 4
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 4
lngCounter = 5
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 5
lngCounter = 6
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 6
lngCounter = 7
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 7
lngCounter = 8
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 8
lngCounter = 9
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 9
lngCounter = 10
Call modProgress.ShowProgress(lngCounter, lngNumberOfTasks, _
, False)
'call ma macro 10Merci beaucoup pour votre aide
Cordialement
Hugues
De rien, merci pour ton retour et tes conseils d'aménagement.