[excel] formulation d'une variable

Résolu
Bonjour à tous,

Je commence à pouvoir bidouiller sur la macro Excel, mais les variables me posent encore problème. C'est pourquoi je souhaiterai avoir votre avis pour le cas suivant :

J'ai une formule, intégrée à une macro plus grande, que je dois répéter 25 fois, chaque fois pour une valeur différente (de 1 à 25). Voici la formule macro :

'La c'est pour comptabiliser les périodes de 1 mois
Range("Q" & Range("Q65536").End(xlUp).Row + 1).Select
Range("Q2", ActiveCell.Offset(-3, 0)).Select
For Each Cell In Selection
If Cell.Value = 1 And IsEmpty(Cell.Offset(0, 1)) And IsEmpty(Cell.Offset(0, 3)) And IsEmpty(Cell.Offset(0, 4)) Then
total1m = total1m + 1
End If
Next
Range("T" & Range("T65536").End(xlUp).Row + 1).Select
Range("T2", ActiveCell.Offset(-1, 0)).Select
For Each Cell In Selection
If Cell.Value = 1 And IsEmpty(Cell.Offset(0, 1)) Then
total1m = total1m + 1
End If
Next
If total1m > 0 Then
Totalt = Totalt + 1
End If


Il me faut répéter la formule en changeant uniquement les chiffres que j'ai mis en gras (il apparait 7 fois dans ce petit bout de macro), mais j'aimerais ne pas avoir à recopier cette formule 25 fois, d'où le besoin de connaître un peu mieux les variables. Si vous pouviez m'éclairer là dessus, je vous en serait très reconnaissant et vous m'aideriez à progresser en macro. N'hésitez pas à me mettre des explications en chemin, ca ne peut que m'aider à comprendre ce que je fais.

Merci d'avance !
Configuration: Windows XP
Firefox 2.0.0.12

52 réponses

Résumé de la discussion

Le problème central est de répéter une macro Excel 25 fois avec des valeurs différentes (1 à 25) sans recopier manuellement le code, afin de calculer des totaux mensuels. Des solutions consistent à extraire les chiffres dans des paramètres d’une procédure (par exemple ByVal j, A, B, C, D) et à appeler cette fonction 25 fois, évitant ainsi la duplication du code. D'autres préconisent d'utiliser des tableaux pour stocker les totaux (par exemple tabTotalm et tabTotalmd) et de récupérer les résultats par index lors de l'étape suivante. En pratique, on peut passer par des modules dédiés et des boucles contrôlées pour initialiser et stocker les valeurs, ce qui permet d’éviter les séquences répétitives et d’améliorer la lisibilité du code.

Bobot (l’IA à votre service)
  1. Je te remercie, mais j'avais déjà trouvé les lignes de code et la présentation par barre des taches pour ces derniers points. Je devrais donc réussir sans trop de problème à les insérer.

    Et je ne veux pas pas non plus te monopoliser pour faire fonctionner uniquement mon programme. D'autres ont surement besoin de tes lumières ! Mais je garde en tête ta proposition d'aide pour le prochain programme que je pourrais être amené à faire.

    Merci encore ! ^^
    1. Arrêtes ... je suis pas trop fort ... la programmation c'est mon job ... même si je ne connais pas Excel, je peux me débrouiller pour coder des petites choses.

      En fait, c'est quoi une Macro ? juste un code qui permet d'exécuter des tâches. Le terme Macro vient juste du fait que Excel propose une fonctionnalité qui permet de les enregistrer automatiquement, sans même connaitre le langage VBA. Il suffit de faire -> nouvelle Macro et d'exécuter ce que l'on veut faire (ex : recopie automatique de cellule) et de faire
      -> terminer Macro. Ce que l'on ne voit pas, c'est qu'un module a été créé dans l'éditeur avec le code VBA associer à la Macro.

      On peut également, si l'on a des connaissances en VBA, se faire la Macro par le code. Ce n'est ni plus ni moins ce que j'ai fait. Je n'appelle pas ça des macros, mais des procédures ou des fonctions. Pour créer un module "code", il faut faire pareil : "insertion" -> "module" ... et d'y placer le code qui va bien ... Dans la fenêtre en bas à gauche je renomme le module.

      Tu dis : Une dernière chose ... comme c'est dommage ... lol ... il aurait été intéressant de rendre ton zinzin plus fonctionnel ... :o) ... par exemple de mettre un bouton sur ta première feuille pour lancer l'exécution des "macros", en faisant au sorte de n'avoir qu'un seul click à faire. Et ensuite, envisager une sauvegarde automatique sans passer par la boîte de dialogue traditionnelle ... et surement plein d'autres choses ... :o))

      Bon courage,

      Ca m'a fait vraiment très plaisir de t'aider.

      Je reste à ta dispo Okazou ...

      ;o)

      Polux
      1. T'es trop fort ! ^^

        Merci BEAUCOUP !!

        Une dernière chose : Pour créer une macro, on fait "insertion" - "module", mais comment tu crées les fenêtres "Code" comme dans ton programme ?
        1. rere,

          voilà comment trouver le chemin :

          Chemin = thisWorkbook.Path


          pour vérifier, juste dessous tu mets :

          MsgBox Chemin


          tu l'effaceras ensuite si c'est ce que tu voulais.

          ;o)

          Polux
          1. re,

            Oui je sais comment faire ça, mais je suis plutôt à la bourre là et pas trop le temps de chercher ... je vais faire de mon mieux pour te trouver ça au plus tôt ...

            ;o)

            polux
            1. Merci beaucoup ! C'est très gentil ! ^^

              Je suis aussi sur un autre problème donc je peux attendre sans souci cet après midi.

              De manière tout à fait accessoire, est ce que tu connais la commande macro qui permet de connaitre le chemin où se trouve le fichier, mais sans le nom du fichier ?

              Cette commande ne m'aide pas comme je le souhaiterai :
              Chemin = ActiveWorkbook.FullName


              Par exemple si le fichier se trouve à l'endroit

              C:Patin/couffin/tintin/fichierExcel.xls

              Je souhaiterai connaitre la commande (si elle existe) qui me permet de détecter (et m'en servir) seulement :

              C:Patin/couffin/tintin/
              1. Bonjour,

                Je suis content que tu aies réussi à faire marcher ton zinzin ... :o) ...

                Tu n'abuses pas de mon temps, j'aide volontier les personnes dans la mesure de mon temps disponible. Sinon je ne le ferai pas ...

                Je pense avoir compris ce que tu veux faire, je suppose que c'est sur la 2ème feuille que tu veux faire ça ...
                Ca doit être possible effectivement. Je ne sais pas encore comment, mais il y a surement une solution.
                Je vais regarder ça ... en espèrant que tu ne sois pas trop pressée ... si c'est pour hier, je ne peux pas ... je suis sur un truc que je dois rendre pour avant-hier ... lol ...
                Je te tiens au courant le plus tôt possible ... disons dans l'après-midi ...

                N'hésites pas pour les questions, si je peux y répondre, ça sera avec grand plaisir.

                ;o)

                Polux
                1. Ca marche ! Quel talent ! ^^

                  Est ce que je peux encore abuser un peu de ton temps ?

                  Comment faire pour que les mois s'affichent par ordre de taille ? De sorte que, par exemple, les périodes de 2,5 mois s'affichent entre les périodes de 2 et 3 mois (si y'a des périodes de 2 ou 3 mois bien sur... enfin je pense que tu as compris ^^)

                  Ensuite j'aurais encore une ou deux questions techniques et j'aurais fini. Merci encore ! :-)
                  1. tout compte fais c'est plus simple par là ... il faut remplacer comptePeriodeMoisDemi par

                    Public Sub comptePeriodeMoisDemi(ByVal j As Double, ByVal A As String, ByVal B As String, ByVal C As String, ByVal D As String)
                    Dim total As Integer
                    
                    Sheets(1).Select
                    
                    total = 0
                    
                        Range(A & Range(A & "65536").End(xlUp).Row + 1).Select
                        Range(B, ActiveCell.Offset(-3, 0)).Select
                        For Each Cell In Selection
                            If Cell.Value = j - 0.5 And Cell.Offset(0, 1).Value = 2 And IsEmpty(Cell.Offset(0, 3)) And IsEmpty(Cell.Offset(0, 4)) Then
                                total = total + 1
                            End If
                        Next
                        
                        Range(C & Range(C & "65536").End(xlUp).Row + 1).Select
                        Range(D, ActiveCell.Offset(-1, 0)).Select
                        For Each Cell In Selection
                            If Cell.Value = j - 0.5 And Cell.Offset(0, 1).Value = 2 Then
                                total = total + 1
                            End If
                        Next
                        
                        tabtotalmd(CInt(j - 0.5)) = total       'stockage dans le tabTotalmd à l'index j - 0.5 (l'index est un entier) -- Cint transforme la valeur en entier
                    
                        If total > 0 Then
                            totalt = totalt + 1
                            totalts = totalts + 1
                        End If
                    
                    End Sub
                    
                    


                    maintenant ça devrait le faire ... enfin j'espère.

                    ;o)

                    polux
                    1. oui, je suis d'accord avec toi et c'est exactement ce qu'il y dans configMoisDemi ...
                      le problème ne vient pas de là ... il vient du module ModComptabilise. Je pense que ça vient de la procédure comptePeriodeMoisDemi.

                      Il n'y a pas de valeur dans le tableau tabTotalmd ...

                      oups je crois avoir trouvé ... je corrige et je t'envoi le nouveau fichier
                      1. Dans ma macro initiale, c'était demandé sous cette forme (exemple pour 7,5 mois)

                        'affichage éventuel pour une durée de 7.5 mois
                        If total7md > 0 Then
                        ActiveCell.Value = total7md
                        ActiveCell.Offset(0, 2).Select
                        ActiveCell.Value = 7.5
                        ActiveCell.Offset(0, 1).Select
                        ActiveCell.Value = "months"
                        ActiveCell.Offset(0, 1).Select
                        ActiveCell.FormulaR1C1 = "=Tarif"
                            Selection.Copy
                            Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
                            False, Transpose:=False
                            Application.CutCopyMode = False
                        ActiveCell.Offset(1, -4).Select
                        End If


                        Donc les "md" devrait apparaitre avec les "s" et les "m"

                        Je sens que mon crâne commence à fumer ! :-)
                        1. es-tu sûr qu'il doit y avoir une valeur pour le total pour les périodes de mois et demi ? je ne trouve aucun élément dans le tableau ?
                          1. Ca marche pas chez moi... :'-(

                            Même après la correction, il persiste à ne pas vouloir m'afficher les périodes de mois et demi !!

                            Tu peux m'envoyer ton fichier corrigé stp ??
                            1. Ca commence à rentrer ! :-)

                              Bon... je teste ca tout de suite et je te dis si ca marche.
                              1. bravo ... c'est presque ça ... :o)) ...

                                Tu as raison pour la première partie, la procédure reçoit "i" comme paramètre ... et l'erreur se situe ici :
                                    If ModComptabilise.tabtotalmd(CInt(j - 0.5)) > 0 Then
                                        ActiveCell.Value = ModComptabilise.tabtotalmd(CInt(j - 0.5))
                                


                                Il faut remplacer "j" par "i", ça donne :

                                    If ModComptabilise.tabtotalmd(CInt(i - 0.5)) > 0 Then
                                        ActiveCell.Value = ModComptabilise.tabtotalmd(CInt(i - 0.5))
                                


                                Pour la deuxième partie, effectivement je passe la valeur de "j" en paramètre, mais la procèdure qui
                                réceptionne cette valeur peut prendre un nom quelconque comme variable de réception de
                                la valeur de "j" ... j'aurai pu écrire ceci :

                                Public Sub configMoisDemi(ByVal toto As Double)
                                
                                Sheets(2).Select
                                'Range("pax").Select
                                
                                'affichage éventuel pour une durée d'un mois 1/2
                                    If ModComptabilise.tabtotalmd(CInt(toto- 0.5)) > 0 Then
                                        ActiveCell.Value = ModComptabilise.tabtotalmd(CInt(toto- 0.5))
                                        ActiveCell.Offset(0, 2).Select
                                        ActiveCell.Value = toto
                                        ActiveCell.Offset(0, 1).Select
                                        ActiveCell.Value = "months"
                                ...
                                


                                Le résultat est le même ...

                                Bravo encore de l'avoir débeugué ... le métier rentre .. :o)

                                J'espère que tu y vois un peu plus clair sur les variables et la façon de les utiliser.

                                N'hésite pas si tu as d'autres questions

                                Bon courage

                                ;o)

                                polux
                                1. Bon... après avoir testé... ca ne vient pas de là.

                                  Je sèche un peu là...
                                  1. Il semble que la valeur pour les mois et demi soit stocké en "j", or tu lui demande d'afficher "i"

                                    Public Sub configMoisDemi(ByVal i As Double)
                                    
                                    Sheets(2).Select
                                    'Range("pax").Select
                                    
                                    'affichage éventuel pour une durée d'un mois 1/2
                                        If ModComptabilise.tabtotalmd(CInt(j - 0.5)) > 0 Then
                                            ActiveCell.Value = ModComptabilise.tabtotalmd(CInt(j - 0.5))
                                            ActiveCell.Offset(0, 2).Select
                                            ActiveCell.Value = i
                                            ActiveCell.Offset(0, 1).Select
                                            ActiveCell.Value = "months"
                                            ActiveCell.Offset(0, 1).Select
                                            ActiveCell.FormulaR1C1 = "=Tarif"
                                                Selection.Copy
                                                Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
                                                False, Transpose:=False
                                                Application.CutCopyMode = False
                                            ActiveCell.Offset(1, -4).Select
                                        End If
                                    
                                    End Sub
                                    


                                    Pourtant si j'en juge d'après cette macro, "i" ne semble pas sollicité (en tout cas pas pour les mois et demi).
                                    Public Sub configureFeuille2()
                                    Dim i As Integer
                                    Dim j As Double
                                    
                                        'sélection de la première case pour commencer à remplir les lignes
                                        Range("pax").Select
                                    
                                        For i = 1 To 3
                                            Call ModConfigFeuil2.configSemaine(i)
                                        Next i
                                    
                                        For i = 1 To 25
                                            Call ModConfigFeuil2.configMois(i)
                                        Next i
                                    
                                        For j = 1.5 To 24.5
                                            Call ModConfigFeuil2.configMoisDemi(j)
                                        Next j
                                    
                                        activeFormule       'Appel la procédure activeFormule
                                    
                                    End Sub


                                    Ca pourrait pas venir de là ??
                                    1. Trop gentil !! ^^

                                      Tout marche bien, sauf les durées en mois et demi. Celles là ne s'affichent pas (je confesse que je n'ai pas encore regardé la macro pour voir la cause)
                                      • 1
                                      • 2
                                      • 3