[Active X] - Affecter un même code de clic à plusieurs boutons différents

Bonjour,

Dans mon fichier je génère automatiquement des boutons (les boutons sont des contrôles Active X de type commadbutton1) et j'aimerai leur attribuer chacun une macro sur leur commande clic. Cependant puisque je ne peux pas créer la commande click (le bout de code nomBouton_click) de chaque bouton à l'avance j'aimerais attribuer la même commande de click à plusieurs boutons. Mon problème étant que chaque bouton a un nom différent et que la seule façon que j'ai trouvée d'attribuer une macro click est par le .Name du bouton.

Est il possible de référencer la commande click d'un bouton autrement que par son nom ?

Merci d'avance pour le temps passé à me lire,

KiraWashi

Bonjour KiraWashi et

Une petite présentation ICI serait la bienvenue

Si vous ne l'avez pas encore fait, je vous invite à lire la charte du forum [A LIRE AVANT DE POSTER]
qui vous aidera dans vos demandes et réponses sur ce forum et notamment :

  • Joignez (si possible) un fichier pour augmenter vos chances d'obtenir de l'aide en cliquant sur le bouton Fichier de l'éditeur. Si votre fichier est trop lourd ou contient des données personnelles, créez une version allégée de votre fichier avec juste assez d'informations pour permettre de comprendre votre problème. Dans tous les cas, ne postez JAMAIS de fichiers avec des informations personnelles ou confidentielles (cet utilitaire peut vous aider à les retirer).

Par avance merci, bonne participation

Cordialement

Présentation faite, pour le fichier je ne peux pas le partager puisqu'il contient des données persos, je peux cependant poser des bouts de code si il est nécessaire de clarifier mes propos.

KiraWashi

bonjour,

Il faudra être beaucoup plus explicite Des boutons ou ? Une feuille ? Plusieurs feuilles ?

Pour quoi faire ? Ils font tous la même chose et s'ils font de choses différentes préciser.

Fournir impérativement un fichier dans un contexte permettant de comprendre et de tester.

Vos données perso on s'en fout. Ce qui est important c'est de comprendre et de tester.

A+

Bonjour galopin,

Je suis au travail et je ne peux pas mettre des fichiers en ligne.

Tous mes boutons sont crées sur une même feuille "Interface". Pour expliquer un peu mieux toutes les informations de ces boutons sont stockés dans la feuille "Catégories" ou "Tous les fichiers". Le boutons font tous la même chose dans le sens où ils appellent la même macro en changeant un paramètre (qui est le nom du bouton) que j'utilise par la suite dans la macro.

image

Ce que je voudrais donc c'est que chaque bouton de "type" catégories références la macro Category_click ci dessous, sans que les boutons aient le même nom .Name:

Private Sub Category_Click()
    Call AfficherSuite(Application.Caller, , True)
End Sub

Function CreerBouton(title As String, Optional inCategory As Boolean, Optional inMenu As Boolean, Optional inFavorite As Boolean) As Boolean
    '
    'Fonction qui permet de créer une forme/bouton dans l'interface (Feuille de calcul interface)
    '
    ' Si aucuns booléens sont renseignés on assume que le bouton est celui d'un fichier
    '
    'title=Nom du fichier,de la catégorie, du favoris ou du Menu que l'on va transformer en Bouton, son bouton aura ce nom
    'Top= coordonnée en hauteur du bouton (distance du bouton avec le haut de la feuille de calcul interface)
    'Left = coordonnée en largeur du bouton (distance du bouton avec le côté gauche de la feuille de calcul interface)
    'inCategory=booléen qui indique si le bouton est celui d'une catégorie et donc dans quelle feuille il faut aller chercher ses informations
    'inMenu=booléen qui indique si le bouton est celui d'un Menu
    'inFavorite=booléen qui indique si le bouton est celui d'un favoris

    'On déclare les variables qui contiendront les données nécessaires pour afficher la forme
    Dim category As String
    Dim linkFile As String
    Dim linkImage As String
    Dim Top As Double
    Dim Left As Double
    Dim Height As Double
    Dim Width As Double
    Dim ColorShape As String
    Dim ColorText As String
    Dim SizeText As Integer
    Dim Police As String
    Dim Visible As Boolean

    'Notre indice
    Dim i As Integer

    'la commande qui sera ensuite lié au bouton placée dans Interface
    Dim Command As String

        'On vérifie que la ligne qu'on cherche est bien renseignée
        If title <> "" And BoutonExiste(title) = False Then
            If inCategory = True Then
                 'On va chercher les infos dans la feuille Catégories
                ThisWorkbook.Worksheets("Catégories").Activate
            ElseIf inMenu = True Then
                 'On va chercher les infos dans la feuille Menu
                ThisWorkbook.Worksheets("Menu").Activate
            ElseIf inFavorite = True Then
                 'On va chercher les infos dans la feuille Mes favoris
                ThisWorkbook.Worksheets("Mes favoris").Activate
            Else
                'On va chercher les infos dans la feuille Tous les fichiers sinon
                ThisWorkbook.Worksheets("Tous les fichiers").Activate
            End If

            'on vérifie qu'on trouve bien le fichier dans
            If Not ActiveSheet.Columns(1).Find(what:=title) Is Nothing Then

                'Dans le cas ou on travaille sur les feuilles favoris ou Tous les fichiers on a la ligne Catégorie et linkFile en plus
                 If (inCategory = False And inMenu = False) Then
                    i = 1
                    category = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    linkFile = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    'Le nom de la forme contient le nom du fichier et le nom de la catégorie dont il dépend
                    strNom = title '+ "_" + category
Données_Menu_Catégories:
                    linkImage = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                   Top = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    Left = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    Height = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    Width = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    ColorShape = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    ColorText = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    SizeText = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    Police = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    ActiveSheet.Columns(1).Find(what:=title).Offset(0, i) = True

                ElseIf inCategory = True Or inMenu = True Then
                    i = 2
                    strNom = title
                    GoTo Données_Menu_Catégories
                End If

                 With ActiveWorkbook
                     With .Worksheets("Interface")
                         'X = .OLEObjects.CountSS
                         Set newButton = .OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False, DisplayAsIcon:=False, Left:=Left, Top:=Top, Width:=Width, Height:=Height)
                     End With

                     With newButton
                         .name = TexteSansEspaces(title) 'le nom du bouton lui même en tant qu'objet
                         .Object.caption = title 'ce qui est afficher sur le bouton
                         .Visible = True
                     End With
                     With newButton.Object
                         .BackColor = StringToRgb(ColorShape)
                         .FontSize = SizeText
                         .FontName = Police
                         .ForeColor = StringToRgb(ColorText)
                    End With
                End With
                CreerBouton = True
            Else
                CreerBouton = False
            End If
        Else
            CreerBouton = False
        End If
End Function

Je vous mets également ma macro de création de bouton à partir de mes feuilles de calcul.

Désolé d'avance pour la taille du message et merci pour ton aide,

KiraWashi

Bonjour à tous,

Oui, je pense que c'est possible en utilisant la fonction callbyname et en variabilisant le fameux paramètre qui dépend du nom du bouton.

Cdlt,

Merci pour ta réponse 3GB,

Je ne suis pas sur de comprendre comment je dois m'y prendre. Tu penses qu'il faut j'utilise CallByName à quelle endroit ?

KiraWashi

Excuse-moi, j'ai l'impression que j'ai répondu un peu vite et que ce n'est pas forcément nécessaire...

En fait, je dirais plutôt qu'il faut gérer les évènements click de façon dynamique et donc probablement passer par un module de classe.

Une première idée :

'MODULE DE CLASSE A NOMMER "MYOLEO"
public withevents CmdBtn as msforms.commandbutton 'en tête de module

private sub CmdBtn_Click()
AfficherSuite CmdBtn.name, , True
end sub

'NB : On peut éventuellement rapatrier la macro AfficherSuite dans le module de classe

'MODULE DE LA FEUILLE CONTENANT LES CommandButton ActiveX
dim tBtn() as new MYOLEO 'en tête de module

private sub worksheet_activate()
for each oleo in me.oleobjects
    n = n + 1: redim preserve tBtn(1 to n): Set tBtn(n).CmdBtn = oleo.object 'doute ici, pas encore testé le .object
next oleo
end sub

private sub worksheet_deactivate()
erase tBtn
end sub

Cela suppose, à chaque création dynamique, de désactiver la feuille Interface (si celle-ci est active) pour mettre à jour la variable tBtn.

Cdlt,

Alors si j'ai bien compris, l'idée serait de crée ma propre classe de bouton de types Catégories. Comment je fais ensuite pour différencier le comportement pour les boutons de commande classiques de ceux de ma classe crée?
La commande en dessous dirigent tous les événements de type commandButton non ?

public withevents CmdBtn as msforms.commandbutton 'en tête de module

Merci pour tes idées. Je vais creuser l'idée de crée mon propre type de bouton.

Oui, c'est plus ou moins ça.

On crée une classe qui intègre une proto-propriété de type MSFORMS.CommandButton et qui gère par la même occasion l'évènement click.

Ensuite, sur le module de classe de la feuille Interface, on affecte un tableau de type MYOLEO (la classe en question), ayant une portée sur la feuille, avec chaque commandbutton activex pour qu'ils réagissent tous à l'évènement click indifféremment.

Les commandbutton classiques ne sont pas concernés normalement. Tous les objets hors de la feuille non plus. Et il est possible de restreindre en conditionnant l'affectation. Ex avec ceux qui commencent par "OK" :

private sub worksheet_activate()
for each oleo in me.oleobjects
    if oleo.name like "OK*" then
        n = n + 1: redim preserve tBtn(1 to n): Set tBtn(n).CmdBtn = oleo.object 'doute ici, pas encore testé le .object
    end if
next oleo
end sub

Ici, je suppose aussi que la feuille ne contient pas d'ActiveX d'un autre type. Sinon, il faudra rajouter une condition.

Voilà, mais essaie de coller les codes pour voir s'ils marchent directement.

Bonjour,

Je reprends donc sur le bon sujet, je ne comprends pas l'intérêt de la variable tbtn ni ce que fait la ligne :

redim preserve tBtn(1 to n): Set tBtn(n).CmdBtn = oleo.object 'doute ici, pas encore testé le .object

Pourrais-tu me l'expliquer?
Je ne sais pas dans quel module tu veux que je place les codes de tes derniers messages.

Merci pour ton aide je m'en sors pas trop avec ce problème d'attribution des macros (je vais clore l'autre fil de discussion).

La dernière version de mon fichier :

9cockpit-v1-0.xlsm (21.21 Ko)

Bonjour KiraWashi,

J'ai précisé sur mon commentaire du 3/12/21 à 13:10 https://forum.excel-pratique.com/excel/active-x-affecter-un-meme-code-de-clic-a-plusieurs-boutons-di... où il fallait placer les codes.

La variable tBtn est un tableau d'objets MYOLEO (l'objet de la classe en question qui gère notamment les évènements sur les commandbutton). Elle a une portée sur toute la feuille contenant les boutons et c'est donc elle qui stocke les commandbutton et permet la centralisation des évènements.

redim preserve tBtn(1 to n) 'redimensionne tBtn à n éléments pour accueillir un nouveau bouton
Set tBtn(n).CmdBtn = oleo.object 'affecte à la propriété CmdBtn de l'élément n (de type MYOLEO) du tableau tBtn le commandbutton (activeX) en cours

Le code de mon dernier message n'est qu'une modification du code précédent et est à placer sur le module de la feuille contenant les boutons.

Cdlt,

Bonjour,

Du coup si j'ai bien compris tbtn nous permets d'avoir une tableau de bouton différent de la collection OLEObjects de la feuille interface, dans laquelle on pourra mettre tous les boutons d'un certain type.
J'ai réalisé quelque tests après la modification des événements de ma feuille interface pour arriver à ce code:

Public WithEvents CmdBtn As CommandButton 'en tête de module

 'Private Sub Catégories_Click()
 '   Call AfficherSuite("Catégories")
'End Sub
'Private Sub MesFavoris_Click()
 '   Call AfficherSuite("Mesfavoris")
'End Sub
'Private Sub Retour_Click()
'    Call AfficherSuite("Retour")
'End Sub

'Private Sub Touslesfichiers_Click()
 '   Call AfficherSuite("Touslesfichiers")
'End Sub

Private Sub CmdBtn_Click()

    'Si le bouton est une catégorie son nom commence par Cat_
    'pour tous les boutons qui commence par Cat_ on appelle donc la fonction afficherSuite en lui indiquant le nom du bouton et son type
    If CmdBtn.name Like "Cat_*" Then
        Call AfficherSuite(CmdBtn.name, , True)

    ElseIf CmdBtn.name = "Catégories" Then
        Call AfficherSuite("Catégories")

    ElseIf CmdBtn.name = "Mesfavoris" Then
        Call AfficherSuite("Mesfavoris")

    ElseIf CmdBtn.name = "Touslesfichiers" Then
        Call AfficherSuite("Touslesfichiers")
    End If

Cependant le clic sur les boutons dont les noms commence par Cat_ ne provoque rien alors que la fonction afficherSuite est censé faire une MsgBox.

Le problème se trouve peut être dans la fonction afficherSuite...

Encore merci pour ton aide.

KiraWashi

10cockpit-v1-0-1.xlsm (21.00 Ko)

Bonjour KiraWashi,

C'est plus ou moins ça. tBtn est un tableau d'éléments de la classe en question. Cette classe héberge une variable publique (plus ou moins l'équivalent d'une propriété) gérant les évènements. C'est pour ça qu'on affecte tBtn(n).CmdBtn = oleo.object et non tBtn(n) = oleo.object.

Je reposte le code que j'avais posté avec un changement de nom et des explications plus précises :

1/ On insère un module de classe (VBE/Insertion/Module de classe)

2/ On le renomme "BtnEvents" par exemple

3/ On y colle le code suivant :

'MODULE DE CLASSE "BtnEvents"
public withevents CmdBtn as msforms.commandbutton 'en tête de module

private sub CmdBtn_Click()
AfficherSuite CmdBtn.name, , True
end sub

'NB : On peut éventuellement rapatrier la macro AfficherSuite dans le module de classe

4/ On se rend sur le module de la feuille qui contient les boutons ActiveX pour y placer ce code :

'MODULE DE LA FEUILLE CONTENANT LES CommandButton ActiveX
dim tBtn() as new BtnEvents 'en tête de module

private sub worksheet_activate()
for each oleo in me.oleobjects
    n = n + 1: redim preserve tBtn(1 to n): Set tBtn(n).CmdBtn = oleo.object
next oleo
end sub

private sub worksheet_deactivate()
erase tBtn
end sub

A l'activation de la feuille, tBtn est affectée et conservée en mémoire, de sorte que les procédures click se produisent indifféremment. A la désactivation de la feuille, cette variable est écrasée. A chaque réactivation de la feuille, tBtn incorporera les éventuels nouveaux commandbutton ActiveX créés dynamiquement (il faut seulement que la création se fasse quand la feuille n'est pas active ou alors désactiver/réactiver la feuille). Sinon, il est possible de mettre à jour tBtn au niveau du code de création dynamique des boutons (ce serait plus académique et clair)...

Sinon, je n'ai pas idée du contenu du code AfficherSuite mais il faudrait effectivement commencer par un simple msgbox pour contrôler.

Cdlt,

Bonjour 3GB,

J'ai fait d'autres modifications entre temps. Comment je fais pour ensuite créer des boutons de commandButton du type Btns_Events qu'on a crée ?
J'aimerai si possible pouvoir adapter le code que j'ai fait précédemment pour la création de bouton de control Active X :

Function CreerBouton(title As String, Optional inCategory As Boolean, Optional inMenu As Boolean, Optional inFavorite As Boolean) As Boolean
    '
    'Fonction qui permet de créer une forme/bouton dans l'interface (Feuille de calcul interface)
    '
    ' Si aucuns booléens sont renseignés on assume que le bouton est celui d'un fichier
    '
    'title=Nom du fichier,de la catégorie, du favoris ou du Menu que l'on va transformer en Bouton, son bouton aura ce nom
    'Top= coordonnée en hauteur du bouton (distance du bouton avec le haut de la feuille de calcul interface)
    'Left = coordonnée en largeur du bouton (distance du bouton avec le côté gauche de la feuille de calcul interface)
    'inCategory=booléen qui indique si le bouton est celui d'une catégorie et donc dans quelle feuille il faut aller chercher ses informations
    'inMenu=booléen qui indique si le bouton est celui d'un Menu
    'inFavorite=booléen qui indique si le bouton est celui d'un favoris

    'On déclare les variables qui contiendront les données nécessaires pour afficher la forme
    Dim category As String
    Dim linkFile As String
    Dim linkImage As String
    Dim top As Double
    Dim left As Double
    Dim height As Double
    Dim width As Double
    Dim ColorShape As String
    Dim ColorText As String
    Dim SizeText As Integer
    Dim Police As String
    Dim Visible As Boolean

    'variable qui sera devant le nom du bouton pour pouvoir inidquer le type du bouton
    Dim btnType As String

    'Notre indice
    Dim i As Integer

    'la commande qui sera ensuite lié au bouton placée dans Interface
    Dim Command As String

        'On vérifie que la ligne qu'on cherche est bien renseignée
        If title <> "" And BoutonExiste(title) = False Then
            If inCategory = True Then
                 'On va chercher les infos dans la feuille Catégories
                ThisWorkbook.Worksheets("Catégories").Activate

                btnType = "Cat_" 'Montrer que le bouton est celui d'une catégorie dans son nom

            ElseIf inMenu = True Then
                 'On va chercher les infos dans la feuille Menu
                ThisWorkbook.Worksheets("Menu").Activate

                btnType = "Menu_" 'Montrer que le bouton est celui d'un Menu dans son nom

            ElseIf inFavorite = True Then

                 'On va chercher les infos dans la feuille Mes favoris
                ThisWorkbook.Worksheets("Mes favoris").Activate
                btnType = "Fav_"   'Montrer que le bouton est celui d'un favoris dans son nom
            Else
                'On va chercher les infos dans la feuille Tous les fichiers sinon
                ThisWorkbook.Worksheets("Tous les fichiers").Activate
                btnType = "File_" 'Montrer que le bouton est celui d'un fichier dans son nom
            End If

            'on vérifie qu'on trouve bien le fichier dans
            If Not ActiveSheet.Columns(1).Find(what:=title) Is Nothing Then

                'Dans le cas ou on travaille sur les feuilles favoris ou Tous les fichiers on a la ligne Catégorie et linkFile en plus
                 If (inCategory = False And inMenu = False) Then
                    i = 1
                    category = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    linkFile = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    'Le nom de la forme contient le nom du fichier et le nom de la catégorie dont il dépend
                    strNom = title '+ "_" + category
Données_Menu_Catégories:
                    linkImage = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                   top = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    left = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    height = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    width = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    ColorShape = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    ColorText = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    SizeText = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    Police = ActiveSheet.Columns(1).Find(what:=title).Offset(0, i)
                    i = i + 1
                    ActiveSheet.Columns(1).Find(what:=title).Offset(0, i) = True

                ElseIf inCategory = True Or inMenu = True Then
                    i = 2
                    strNom = title
                    GoTo Données_Menu_Catégories
                End If

                 With ActiveWorkbook
                     With .Worksheets("Interface")
                         'X = .OLEObjects.CountSS
                         Set newButton = .OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False, DisplayAsIcon:=False, left:=left, top:=top, width:=width, height:=height)
                     End With

                     With newButton
                         .name = btnType + TexteSansEspaces(title) 'le nom du bouton lui même en tant qu'objet
                         .Object.caption = title 'ce qui est afficher sur le bouton
                         .Visible = True
                     End With
                     With newButton.Object
                         .BackColor = StringToRgb(ColorShape)
                         .FontSize = SizeText
                         .FontName = Police
                         .ForeColor = StringToRgb(ColorText)
                    End With
                End With
                CreerBouton = True
            Else
                CreerBouton = False
            End If
        Else
            CreerBouton = False
        End If
End Function

Je pense que les modifications se trouvent sur la ligne :

Set newButton = .OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False, DisplayAsIcon:=False, left:=left, top:=top, width:=width, height:=height)

Mais je ne vois pas trop comment je fais pour créer le bouton en spécifiant son type.

Je te laisse mon fichier si tu as des questions (je le change tous les jours donc je te le redépose).

Merci pour ton aide,

KiraWashi

17cockpit-v1-0-2.xlsm (22.99 Ko)
Rechercher des sujets similaires à "active affecter meme code clic boutons differents"