XL 2013 Répétition de code

RENAUDcyrille

XLDnaute Nouveau
bonjour tous
J'ai des lignes de code que je doit répéter plus de 25 fois, et cela est un peu gavant car dès que je veux faire une modif dans mon code il faut le faire 25 fois.
j'ai cherché un peu partout ici et sur d'autre site mais je ne trouve pas comment faire pour réduire ces lignes répétitives. D'où mon appel à l'aide.

Voici le topo.
J'ai plusieurs groupe d'objet répétitif comme suivant :
- chaque groupe est composé d'une optionbutton qui sont indicés ex : groupe TA, j'ai optionbuttonTA1, groupe AD j'ai otionbuttonAD ... soit des groupes XX avec OptBXX1
- dans chaque groupe j'ai 2 commandbutton qui sont indicés ex ; groupe TA, j'ai commandbuttonTA11 et commandbuttonTA10, groupe AD j'ai commandbuttonAD11 et commanduttonAD10... soit des groupes XX avec des CdBXX11 et CdBXX10
- pour chaque groupe si on clique sur les CdBXX11 ont déplace de 10 points OpBXX1 vers la gauche et vers la droite pour le CdBXX10.

Voici mon code pour un groupe :
Private Sub CommandButtonTA10_Click()
If OptionButtonTA1.Left > 315 Then
OptionButtonTA1.Left = OptionButtonTA1.Left
Else
OptionButtonTA1.Left = OptionButtonTA1.Left + 10
End If
End Sub

Private Sub CommandButtonTA11_Click()
If OptionButtonTA1.Left < 10 Then
OptionButtonTA1.Left = OptionButtonTA1.Left
Else
OptionButtonTA1.Left = OptionButtonTA1.Left - 10
End If

End Sub


il y a t il possibilité via module ou module de classe de n'écrire qu'une seule fois ce code pour tous les groupes.
Pour l'instant j'ai copier 25 fois ce code en changeant les indices des OpB et CdB à chaque fois mais c'est lourd ;)

Dans l'attente de votre retour.

Si vous avez besoin de plus d'info je me tiens à votre dispo.
PS je travaille sur Excel2019 mais cela doit être compatible avec les VBA des Excels précédents car je ne serais pas le seul à utilisé le programme.
Merci
salutations
Cyrille
 
Solution
Bonjour RENAUDcyrille, Bernard,

Je vois qu'il n'y a aucun fichier joint alors j'en ai créé deux.

Le 1er fichier avec les boutons dans la feuille de calcul et ce code dans le module de classe :
VB:
Public WithEvents CB As MsForms.CommandButton

Private Sub CB_Click()
Dim OB As Object
Set OB = Feuil1.OLEObjects("OptionButton" & Left(Right(CB.Name, 4), 3))
If Right(CB.Name, 2) = "10" And OB.Left <= 315 Then OB.Left = OB.Left + 10
If Right(CB.Name, 2) = "11" And OB.Left >= 10 Then OB.Left = OB.Left - 10
End Sub
La classe est initialisée dans la Workbook_Open.

Le second fichier avec les boutons dans un UserForm et ce code dans le module de classe :
VB:
Public WithEvents CB As MsForms.CommandButton

Private Sub CB_Click()
Dim...

job75

XLDnaute Barbatruc
Bonsoir RENAUDcyrille,

Pour ne pas avoir à faire une macro pour chaque CommandButton il faut en effet un module de classe.

Nombreux exemples sur le forum.

Pour la macro vous devriez vous rendre compte qu'écrire :
VB:
OptionButtonTA1.Left = OptionButtonTA1.Left
est tout à fait stupide.

A+
 

RENAUDcyrille

XLDnaute Nouveau
Merci pour ce 1er retour
oui je sais que ma ligne est stupide mais je suis partie avec un If à l'envers ;), je compte l'éliminé quand j'aurais compris les modules de classe. car c'est sur ce point que je butte le plus.
j'ai cherché avec les mots clés module de classe mais je n'ai pas tous compris d'où ma demande.
dans l'attente d'un retour
 

Dranreb

XLDnaute Barbatruc
Bonsoir.
Ce curieux besoin devrait pouvoir se résoudre à l'aide d'un module de classe qui contiendrait ça :
VB:
Option Explicit
Private WithEvents CBnGauch As MSForms.CommandButton
Private WithEvents CBnDroit As MSForms.CommandButton
Private OBnDéplc As MSForms.OptionButton
Public Sub Init(ByVal CBnG As MSForms.CommandButton, _
                ByVal CBnD As MSForms.CommandButton, _
                ByVal OBn As MSForms.OptionButton)
   Set CBnGauch = CBnG
   Set CBnDroit = CBnD
   Set OBnDéplc = OBn
   End Sub
Private Sub CBnDroit_Click()
   If OBnDéplc.Left <= 315 Then OBnDéplc.Left = OBnDéplc.Left + 10
   End Sub
Private Sub CBnGauch_Click()
   If OBnDéplc.Left >= 10 Then OBnDéplc.Left = OBnDéplc.Left - 10
   End Sub
Remarque : il devrait être possible de communiquer à la méthode Init des expressions du style Me("CBn" & N + 1) au cas où ce serait faisable par des boucles For N = etc.
 
Dernière édition:

RENAUDcyrille

XLDnaute Nouveau
j'ai oublié de dire que je ne connais le VBA que par recopiage de bout de code et en autoditacte ;)
donc merci pour ton code Dranreb, j'en comprend une partie mais me pose des questions.

comment il fait pour savoir que le CdDTA11 va faire bouger OpbTA1 et non l'OpBAD1?
si j'écris ce code dans un module de classe ou autre (si il faut juste un module simple je prend aussi), et après si je clique sur un CdB, il me bougera le bon OpT?
où je doit appeler ce code dans mon programme?
 

Dranreb

XLDnaute Barbatruc
Si vous spécifiez les 3 bons contrôles à la méthode Init, oui.
En supposant que vous ayez appelé CBnGDOBn le module de classe dont j'ai indiqué le code, la structure générale est :
VB:
Option Explicit
Private ClnCBnGDOBn As New Collection
Private Sub UserForm_Initialize()
   Dim LeTruc As CBnGDOBn
   For ?
      Set LeTruc = New CBnGDOBn
      LeTruc.Init ?, ?, ?
      ClnCBnGDOBn.Add LeTruc
      Next ?
   End Sub
 

RENAUDcyrille

XLDnaute Nouveau
Si vous spécifiez les 3 bons contrôles à la méthode Init, oui.
En supposant que vous ayez appelé CBnGDOBn le module de classe dont j'ai indiqué le code, la structure générale est :
VB:
Option Explicit
Private ClnCBnGDOBn As New Collection
Private Sub UserForm_Initialize()
   Dim LeTruc As CBnGDOBn
   For ?
      Set LeTruc = New CBnGDOBn
      LeTruc.Init ?, ?, ?
      ClnCBnGDOBn.Add LeTruc
      Next ?
   End Sub
pour la ligne le truc.init?,?,? je pense qu'il faut remplacer le ? par les indices des boutons soit TA11, TA1, TA10
mais pour le For ? et le Next je ne vois pas.
DEplus désolé de mes remarques bêtes de novice, mais en faisant ce remplacement je ne gère qu'un groupe celui des TA, et pour les autres groupes?

Si vous spécifiez les 3 bons contrôles à la méthode Init, oui.
En supposant que vous ayez appelé CBnGDOBn le module de classe dont j'ai indiqué le code,...
[/CODE]
Comment on appele le le module de classe CBnGDOBn? j'ai copie le 1er code que tu m'a fournis dans un module de classe qui s’appelle "classe 1" et je en vois pas le nom CBnGDOBn dans ton code?
Merci d'avance
 

Dranreb

XLDnaute Barbatruc
Je ne sais pas, c'est quelque chose comme ça :
VB:
Option Explicit
Private ClnCBnGDOBn As New Collection
Private Sub UserForm_Initialize()
   Dim NomGrp As String, N As Long
   Dim LeTruc As CBnGDOBn
   For N = 1 To 2
      NomGrp = Choose(N, "TA", "AD")
      Set LeTruc = New CBnGDOBn
      LeTruc.Init Me("CBn" & NomGrp & "0"), Me("CBn" & NomGrp & "1"), Me("OBn" & NomGrp)
      ClnCBnGDOBn.Add LeTruc
      Next N
   End Sub
Oui, je ne garde rigoureusement jamais ne nom d'origine sans aucune signification de rien de ce que j'insère dans un projet VBA ni un UserForm. Alors changez sa propriété Name 'Classe1' en 'CBnGDOBn' (pour moi ça veut dire CommandButton gauche/droite et OptionButton)
 
Dernière édition:

RENAUDcyrille

XLDnaute Nouveau
Je ne sais pas, c'est quelque chose comme ça :
VB:
Option Explicit
Private ClnCBnGDOBn As New Collection
Private Sub UserForm_Initialize()
   Dim NomGrp As String, N As Long
   Dim LeTruc As CBnGDOBn
   For N = 1 To 2
      NomGrp = Choose(N, "TA", "AD")
      Set LeTruc = New CBnGDOBn
      LeTruc.Init Me("CBn" & NomGrp & "0"), Me("CBn" & NomGrp & "1"), Me("OBn" & NomGrp)
      ClnCBnGDOBn.Add LeTruc
      Next N
   End Sub
Oui, je ne garde rigoureusement jamais ne nom d'origine de rien de ce que j'insère dans un projet VBA. Alors changez sa propriété Name 'Classe1' en 'CBnGDOBn' (pour moi ça veut dire CommandButton gauche/droite et OptionButton)
Re merci
je commence j'espère à comprendre. Si j'ai 5 groupes je note
For N=1 to 5
NomGrp = Choose(N, "TA1", "TA2", "TA3", "AD1", "AD2")

comme cela cela renvoie les bonnes variable vers le module de classe mais en copiant le code, et en l'exécutant, Excel me répond : "Erreur de compilation, type défini par l'utilisateur non défini" et m'encadre en bleu la ligne " Dim LeTruc As CBnGDOBn"
je pense que c'est lié à cela " En supposant que vous ayez appelé CBnGDOBn le module de classe dont j'ai indiqué le code" comment fait-on?
 

RENAUDcyrille

XLDnaute Nouveau
j'avais pas vu et ne savais pas que c'était possible, maintenant si. Merci.
cela avance.

maintenant Excel me dit "erreur d'éxécution '-2147024809 (80070057) : objet spécifié introuvable."
Cela me pose la question dans la ligne
LeTruc.Init Me("CBn" & NomGrp & "0"), Me("CBn" & NomGrp & "1"), Me("OBn" & NomGrp)
Me je doit le remplacer par le nom de la userform où se trouve les boutons?

j’essaie cette piste en attendant ton retour.
 

Dranreb

XLDnaute Barbatruc
J'ai indiqué l'exemple avec les trigrammes préfixes que j'utilise toujours pour tous les objets avec seulement deux règles selon que leur nom de type comporte une ou plusieurs majuscules, et quelques exceptions. En voici la liste :
1592517728138.png

Si vos noms de TextBox et d'OptionButton suivent d'autre règles et que vous ne pouvez appliquer les miennes, ce sont les votres qu'il faut prendre bien entendu pour que les Me( etc. correspondent à quelque chose d'existant.
 
Dernière édition:

RENAUDcyrille

XLDnaute Nouveau
Merci , c'est la piste que j'ai suivi après réflexion et avant ta réponse. Et en changeant le trigramme par le nom complet et en laissant Me, cela marche.
Merci à toi pour ce dépannage.
Que ta nuit soit bonne, je pense pas revenir t’embêter ce soir.
 

job75

XLDnaute Barbatruc
Bonjour RENAUDcyrille, Bernard,

Je vois qu'il n'y a aucun fichier joint alors j'en ai créé deux.

Le 1er fichier avec les boutons dans la feuille de calcul et ce code dans le module de classe :
VB:
Public WithEvents CB As MsForms.CommandButton

Private Sub CB_Click()
Dim OB As Object
Set OB = Feuil1.OLEObjects("OptionButton" & Left(Right(CB.Name, 4), 3))
If Right(CB.Name, 2) = "10" And OB.Left <= 315 Then OB.Left = OB.Left + 10
If Right(CB.Name, 2) = "11" And OB.Left >= 10 Then OB.Left = OB.Left - 10
End Sub
La classe est initialisée dans la Workbook_Open.

Le second fichier avec les boutons dans un UserForm et ce code dans le module de classe :
VB:
Public WithEvents CB As MsForms.CommandButton

Private Sub CB_Click()
Dim OB As Object
Set OB = UserForm1("OptionButton" & Left(Right(CB.Name, 4), 3))
If Right(CB.Name, 2) = "10" And OB.Left <= 315 Then OB.Left = OB.Left + 10
If Right(CB.Name, 2) = "11" And OB.Left >= 10 Then OB.Left = OB.Left - 10
End Sub
La classe est initialisée avant l'ouverture de l'USF :
VB:
Dim CB() As New Classe1

Private Sub CommandButton1_Click()
Dim c As Control, n%
For Each c In UserForm1.Controls
    If TypeName(c) = "CommandButton" Then
        ReDim Preserve CB(n)
        Set CB(n).CB = c 'initialise la classe
        n = n + 1
    End If
Next
UserForm1.Show
End Sub
A+
 

Pièces jointes

  • Boutons dans feuille(1).xlsm
    33.3 KB · Affichages: 2
  • Boutons dans UserForm(1).xlsm
    25 KB · Affichages: 3
Dernière édition:

Discussions similaires

Réponses
21
Affichages
329

Statistiques des forums

Discussions
312 379
Messages
2 087 765
Membres
103 662
dernier inscrit
rterterert