ProgressBar

ricardd

XLDnaute Nouveau
Bonjour à tous,

J'ai réalisé une macro sur excel 2007 qui effectue tout un tas d'opérations et je souhaiterais y ajouter une barre de progression mais je rencontre quelques problèmes que je n'arrive pas à résoudre malgrés tous les posts sur les porgressbar que je viens de lire.

Le temps d'execution de la macro n'est pas fixe et pour que la progression de la barre soit cohérente sur tous les pc sur lesquels elles sera utilisée, je ne veux pas faire une barre en fonction du temps comme beaucoup de tuto explique. En plus de ça, la macro comprend une vingtaine de boucles dont les parametres sont variables. J'avais donc dans l'idée de changer en plusieurs endroits du code principal la valeur de ma variable de la progressbar.
ex: ligne 1: progress = 0
ligne 50: progress = 30
etc jusqu'à la valeur max.

Le problème que je rencontre c'est que étant donné que j'ai commencé le vba il y a 3 semaines avec cette macro, le code est pas super optimisé (pas génant, la macro n'est exécutée qu'une fois par semaine) mais surtout toutes mes variables (un grand nombre) ne sont pas déclarée aussi proprement qu'il le faudrait et donc qand j'ouvre une autre Sub, elles sont toutes perdues ... (plus génant).

Donc soit je dois faire en sorte que les variables soient perssistantes d'une sub à une autre, soit je dois ajouter le code de la progressbar dans mon code principal sans faire appel à d'autres sub ou fonctions. Or je ne vois pas bien comment faire.

Voici un exemple de ce que j'ai essayé. J'ai inséré ce code dans ma macro principale. Les essais précédents été plus ressemblant à ce que j'ai trouvé sur les forums, c'est à dire un module supplémentaire avec mon code de progressbar , voir aussi le code de la progressbar directement dans la userform, mais je perdais toujours mes nombreuses variables pendant l'execution du code de la barre.

Code:
UserForm1.Image1.Picture = LoadPicture(Access_path & "\A350.jpg")
Cycles = 100
Progress = 0

UserForm1.Show 0
    
If UserForm1.ProgressBar1.Value = Cycles Then
   Unload UserForm1
   Exit Sub
Else
    Function MAJBar(Progress)
        With UserForm1.ProgressBar1
            .Min = 0
            .Max = Cycles
            .Value = Progress
        End With
    End Function
End If
       
' ** MAJ Progress Bar **
    MAJBar (1)
' ******************


' Suite du code de la macro principale


' ** MAJ Progress Bar **
    MAJBar (25)
' ******************

'ETC

Le problème pour le moment c'est qu'il me demande un "End Sub" , or je ne souhaite pas fermer ma sub principale pour ne pas perdre mes variables. D'ailleurs je ne sais même pas si cette façon de faire marche/marchera.

Voila, si quelqu'un a une idée à me soumettre et surtout si quelqu'un a compris mon problème ^^ Parce que je sais pas si j'ai été très clair...

Merci d'avance ;)

Bonne journée.
 

Pierrot93

XLDnaute Barbatruc
Re : ProgressBar

Bonjour,

pas tout compris.... essaye peut être une déclaration de variable "public" dans un module standard. exemple ci-dessous, sur les premières lignes du module :
Code:
Option Explicit
Public mavariable As Long

bonne journée
@+

Edition : bonjour fhoest:)
 

ricardd

XLDnaute Nouveau
Re : ProgressBar

@ fhoest: Dans ces exemple la progressbar ne s'affiche pas dans une userform mais juste en bas de la page, or je voudrais qu'elle s'affiche dans une fenêtre pour une meilleure visibilité.

@ Pierrot93: Désolé, j'apprend sur le tas depuis peu et je ne maitrise pas du tout le sujet donc expliquer mon pbm sans le vocabulaire adéquat ça donne quelquechose de pas très clair ^^

En fait il ne s'agit pas que d'une variable, mais si je souhaite lancer le code de la progressbar qui se trouve dans une autre sub voir un autre module, je veux faire en sorte qu'il garde en mémoire les variables de ma macro principale (soit une cinquantaine), pour qu'une fois le code de la barre executé et quand il poursuit le code de la macro principal, il puisse utiliser les variables précédemment définies.
Mais si il existe une façon de faire sans devoir déclarer la cinquantaine de variable de cette façon "Public mavariable As Long", ça m'arrangerai.
D'où mon essai d'inclure le code de la progressbar dans mon code principal (l'exemple que j'ai mis dans le message d'avant), mais ça ne marche pas :s


Merci pour vos réponses
 

fhoest

XLDnaute Accro
Re : ProgressBar

Bonjour Pierrot,
Pour compléter ce que pierrot tente de t'expliquer c'est de mettre l'instanciation de tes variables dans un modules avec l'instruction public tu garderas la valeurs de ta variable,
tu peux également utilisé un tableau pour tes 50 variables avec ce qu'il te propose tu mets ton End sub. et normalement cela va fonctionner.
tu peux également mettre un fichier exemple cela sera plus simple pour avoir une aide
A+
 
Dernière édition:

Pierrot93

XLDnaute Barbatruc
Re : ProgressBar

Re,

je veux faire en sorte qu'il garde en mémoire les variables de ma macro principale (soit une cinquantaine), pour qu'une fois le code de la barre executé et quand il poursuit le code de la macro principal, il puisse utiliser les variables précédemment définies.

bah... sauf à ce que tes variables soient réinitialisées dans une autre "sub", tu les retrouves une fois rebasculé dans la "sub principale"....
 

ricardd

XLDnaute Nouveau
Re : ProgressBar

@ fhoest: Pour le code je ne suis pas sur que ça aide vraiment, c'est assez long et (je pense) pas très utile pour comprendre ce qui va pas. Mais je peux toujours mettre un bout pour voir comment je déclare mes variables etyc

Code:
'-----------------------------
' Sheet "Top_defect_evolution"
'-----------------------------

' Extracts the row number of the top defects
    
    Workbooks("Clustering_fuselage.xlsm").Sheets("Overview_clustering").Activate
    
    For i = 1 To nb_cluster - 1
        If Cells(4 + b * (nb_cluster + 2) + i, 2).Value = top1_name Then
           top1_row = Cells(4 + b * (nb_cluster + 2) + i, 2).Row
        End If
    Next
    
    For i = 1 To nb_cluster - 1
        If Cells(4 + b * (nb_cluster + 2) + i, 2).Value = top2_name Then
           top2_row = Cells(4 + b * (nb_cluster + 2) + i, 2).Row
        End If
    Next
    
    For i = 1 To nb_cluster - 1
        If Cells(4 + b * (nb_cluster + 2) + i, 2).Value = top3_name Then
           top3_row = Cells(4 + b * (nb_cluster + 2) + i, 2).Row
        End If
    Next
    
' Creates the graph
     
    Dim rngDataSource As Range
    Dim top1_values As Range
    Dim top2_values As Range
    Dim top3_values As Range
    Dim cw_list As Range
    
    Set top1_values = Sheets("Overview_clustering").Range(Cells(top1_row, 3), Cells(top1_row, num_column))
    Set top2_values = Sheets("Overview_clustering").Range(Cells(top2_row, 3), Cells(top2_row, num_column))
    Set top3_values = Sheets("Overview_clustering").Range(Cells(top3_row, 3), Cells(top3_row, num_column))
    Set cw_list = Sheets("Overview_clustering").Range(Cells(2, 3), Cells(2, num_column))
    Set rngDataSource = Sheets("Overview_clustering").Range(Cells(5 + b * (nb_mft + 2), 2), Cells(5 + (b + 1) * (nb_mft + 2), num_column))
    
    Workbooks("Clustering_fuselage.xlsm").Activate
    Sheets("Overview_clustering").Select
    ActiveSheet.Copy After:=Workbooks(Classeur1).Sheets("Target")
   
    Workbooks(Classeur1).Activate
    Sheets("Top_defect_evolution").Activate
    ActiveSheet.Shapes.AddChart.Select
    
    ' Chart Shape
    
    Dim chartsize As Range
    Set chartsize = ActiveSheet.Range("A1:Q33")

    ' Graph data
    
    With ActiveChart
        .ChartType = xlLine
        .SetSourceData Source:=rngDataSource
        .SeriesCollection(1).XValues = cw_list
        .SeriesCollection(1).Name = top1_name
        .SeriesCollection(1).Values = top1_values
        .SeriesCollection(2).Name = top2_name
        .SeriesCollection(2).Values = top2_values
        .SeriesCollection(3).Name = top3_name
        .SeriesCollection(3).Values = top3_values
    End With

Et toutes les variables telles que:
num_column
Classeur1
nb_cluster
etc.
sont crées et les valeurs sont allouées plut tôt dans le code, et je perd tout quand l'execution passe d'une sub à une autre.
Mais je vais essayer ce que vous m'avais dit et je reviens vers vous si j'ai encore un problème.

Merci ;)
 

ricardd

XLDnaute Nouveau
Re : ProgressBar

Effectivement, ça marche bien avec ton code.
Mais ça veut dire que je dois déclarer toutes mes variables de cette façon... ça va être long.
Est-ce que ça marche si je les déclare toutes en "Variant" ou je dois bien préciser si c'est range, long, string etc ?
 

fhoest

XLDnaute Accro
Re : ProgressBar

Re, si tu restes dans le même endroit qui concerne ton userform (sans être dans un module) tu peux déclarer tes variables en simple Dim tout en haut des codes les valeurs des variables ne seront pas réinitialiser sans que tu le fasses toi même exemple
Code:
'a mettre tout en haut 
dim ma_variable as string

Private Sub Userform_click()
ma_variable="Bonjour"
msgbox ma_variable,vbinfo
end sub
 
Private sub commandbutton1_click()
msgbox ma_variable
end sub

Tu peux remarquer que la valeur de ta variable est identique.

par contre si tu fais ceci:

Code:
Private Sub Userform_click()
Dim ma_variable As String

ma_variable = "Bonjour"
MsgBox ma_variable, vbinfo
End Sub
 
Private Sub commandbutton1_click()
MsgBox ma_variable
End Sub
en entrant dans le commandbutton ta variable perd sa valeur donc ton message est vierge.
Et oui il faut déclarer toute tes variables.
A+
 

ricardd

XLDnaute Nouveau
Re : ProgressBar

Re,

Merci mon problème d'origine est réglé. J'ai fait comme suit:

Code:
Sub Variables()
    Variables_list
End Sub

Sub Inflow_overview()
    'Tout mon code de ma macro principale
End Sub


et dans Variables_list

Code:
Option Explicit
Public pdt1
Public pdt2
Public pdt3
Public pdt4
Public pdt5
Public Access_path
Public nb_mft
Public nb_cluster
'ETC ...

Public Sub Variables_list()
    Inflow_overview 
End Sub

Maintenant un nouveau problème apparait. Quand ma userform apparait, le code ne continue pas à s'executer tant que je ne ferme pas la userform manuellement ... or cette userform affiche la progressbar, j'aimerai donc éviter de devoir la fermer :s

Section de la macro principale qui déclenche la progressbar:

Code:
UserForm1.Image1.Picture = LoadPicture(Access_path & "\A350.jpg")
UserForm1.Show

PctDone = 0 / 120000
UpdateProgressBar PctDone

Userform1 code:

Code:
Private Sub UserForm_Activate()
' Largeur de la progressBar à 0
ProgressBar1.Width = 0
End Sub

Et enfin code du module progressbar:

Code:
Sub UpdateProgressBar(PctDone As Single) 
    With UserForm1
        ' Mise à jour du label.
        .Label2.Caption = Format(PctDone, "0%")
        ' Afin de paramétrer la fin de la progressBar par rapport au frame
        .ProgressBar1.Width = PctDone * (.ProgressBar1.Width - 20)   
    End With
    ' DoEvents autorisant au UserForm de ce mettre à jour
    DoEvents   
End Sub


Merci pour le coup des variables et merci d'avance pour ce nouveau pbm :D
 

fhoest

XLDnaute Accro
Re : ProgressBar

A partir du moment ou tu as déclarer test variables en public elles sont accessibles partout tu n'as pas besoins de passer par des sub() du modules pour te diriger dans celui ci ,elles sont initialisé au début et restes active tout au long de l’exécution de code.
en clair cela veut dire
Code:
 '************ ' pas nécessaire**************
Sub Variables()
    Variables_list
End Sub
'*************************


ici ok

Code:
'tu peux laisser le sub origine
Sub Inflow_overview()
    'Tout mon code de ma macro principale
End Sub

et dans Variables_list

Code:
'ici ok
                 [FONT=monospace]Option Explicit
Public pdt1
Public pdt2
Public pdt3
Public pdt4
Public pdt5
Public Access_path
Public nb_mft
Public nb_cluster
'ETC ...
[/FONT]

Code:
'****************[/FONT][code]pas nécessaire**************
Public Sub Variables_list()
    Inflow_overview 
End Sub
'****************************


pour le reste je n'ai pas encore regardé.
mais un petit fichier même tres petit serait le bienvenue
parce que je n'ai pas envie de me taper tout le reste pour faire le test.
A bientôt.
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 884
Messages
2 093 245
Membres
105 658
dernier inscrit
Mario Richard