Assigner une classe à un bouton dans une feuille

Résolu
Ein85 Messages postés 32 Date d'inscription   Statut Membre Dernière intervention   -  
Ein85 Messages postés 32 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour à tous,

J'ai beaucoup de contrôles de type CommandButton et TextBox dans une feuille qui ont un comportement identique. J'ai au départ affecté une macro pour chaque objet, mais le nombre d'objets s'avère maintenant bien plus grand que je ne le pensais à un tel point que si je dois affecter à chaque contrôle sa propre macro, le code devient lourd et indigeste.

Bref, je songe aux modules de classe pour simplifier tout ça.

J'ai trouvé sur le net des exemples permettant d'assigner une classe à un bouton créé à la volée mais rien pour un bouton déjà existant.

L'idée de mon programme serait de faire une loop sur chaque objet concerné et leur assigner une classe comme dans l'exemple primitif suivant:

Code du module de classe:
Option Explicit

Public WithEvents MyClassAction As MSForms.CommandButton

Private Sub MyClassAction_Click()

MsgBox "Hello Word"

End Sub


Code dans la feuille:


Sub test()

Dim cmd As Classe1
Dim obj As OLEObject

For Each obj In ActiveSheet.OLEObjects

'On vérifie que l'objet est un bouton de commande
If Left(obj.Name, 7) = "Command" Then
Set cmd = New Classe1
cmd.MyClassAction = obj 'On assigne la classe à l'objet
End If

Next

End Sub


Bien évidemment ce code ne fonctionne pas, mais l'idée est là, à savoir dans ce cas identifier chaque objet de type CommandButton et leur affecter la classe MyClassAction. Est-il possible d'arriver au résultat voulu avec quelques modifications simples du code ci-dessus?

Merci d'avance!
A voir également:

2 réponses

pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761
 
Bonjour,

Le problème des classes de textbox est qu'elles ne reprennent pas tous les événements des textbox.
Notamment, ne sont pas repris, _GotFocus() et _LostFocus().
Dommage!

Pour contourner cette difficulté, tu dois créer des procédures (GotFocus et LostFocus) qui font ce que tu souhaites lors d'un autre événement.

Quel événement choisir?
Pour qu'un textbox de feuille (je précise bien de feuille) ait le focus, il faut cliquer dedans. (la tabulation, ni aucune autre touche clavier ne permet cela)
L'événement choisit est donc _MouseDown()

Tu dois donc, à l'activation de ta feuille (par exemple), boucler sur tous tes contrôles dans la feuille. Si ce sont des textbox, les implémenter dans ta classe, classe qui va contrôler l'événement MouseDown.
Puis, dans l'événement MouseDown, envoyer vers tes procédures GotFocus et/ou LostFocus.

Un exemple :
Dans le module de la feuille :
Option Explicit

Private Sub Worksheet_Activate()
Set Wsh = Me
Dim Objet As OLEObject, Nbre As Byte

   For Each Objet In ActiveSheet.OLEObjects
      If TypeOf Objet.Object Is MSForms.TextBox Then
         Nbre = Nbre + 1
         ReDim Preserve TxtB(1 To Nbre)
         Set TxtB(Nbre).MyCl = Objet.Object
      End If
   Next Objet
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'fait perdre le focus au dernier textbox lors d'un clic dans la feuille
If CeluiQuiALeFocus <> "" Then LostFocus CeluiQuiALeFocus
End Sub


Dans un module standard :
Option Explicit

Public TxtB() As New Classe1
Public CeluiQuiALeFocus As String
Public Wsh As Worksheet

Sub GotFocus(Txt As String)
   If Wsh.OLEObjects(Txt).Object.Value = "Champ à renseigner" Then Wsh.OLEObjects(Txt).Object.Value = ""
End Sub

Sub LostFocus(Txt As String)
   If Wsh.OLEObjects(Txt).Object.Value = "" Then Wsh.OLEObjects(Txt).Object.Value = "Champ à renseigner"
End Sub


Dans un module de classe nommé Classe1 :
Option Explicit

Public WithEvents MyCl As MSForms.TextBox

Private Sub MyCl_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
   If CeluiQuiALeFocus <> "" Then Call LostFocus(CeluiQuiALeFocus)
   CeluiQuiALeFocus = MyCl.Name
   Call GotFocus(CeluiQuiALeFocus)
End Sub



Un fichier exemple
Si, comme dans mon exemple, la feuille concernée est celle d'ouverture du classeur, son événement Activate ne sera pas déclenché. Il convient donc d'ajouter, dans le module ThisWorkBook :
Option Explicit

Private Sub Workbook_Open()
Worksheets("Feuil2").Activate
Worksheets("Feuil1").Activate
End Sub
2
Ein85 Messages postés 32 Date d'inscription   Statut Membre Dernière intervention  
 
Exactement ce qu'il me fallait. Merci beaucoup!
0
michel_m Messages postés 16602 Date d'inscription   Statut Contributeur Dernière intervention   3 314
 
Bonjour

un exemple de classe avec commandbutton
http://www.cjoint.com/c/FAEm6T3xlpx
1
Ein85 Messages postés 32 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,

Merci pour votre réponse, elle m'a été très utile pour les objets CommandButton. Je bloque cependant sur les objets TextBox. Je souhaiterais leur assigner une classe à deux événements (GotFocus et LostFocus).

L'idée serait la suivante:
Si la textbox est vide, elle affiche lors du LostFocus une valeur par défaut (ex: "Champ à renseigner").
Si la textbox affiche le texte par défaut (donc "Champ à renseigner") lors du GotFocus, alors la textbox devient vide et l'utilisateur peut la renseigner.

J'ai modifié votre code pour la textbox et essayé le code suivant mais ça ne fonctionne pas.

Dans la classe Classe1:

Public WithEvents MyCl As MSForms.TextBox

Private Sub MyCl_GotFocus()

If MyCl.Value = "Champ à renseigner" Then
MyCl.Value = ""
End If
End Sub

Private Sub MyCl_LostFocus()

If MyCl.Value = "" Then
MyCl.Value = "Champ à renseigner"
End If
End Sub


Dans ThisWorkbook:

Dim TxtB() As New Classe1

Private Sub Workbook_Open()
Dim Objet As OLEObject, Nbre As Byte

For Each Objet In ActiveSheet.OLEObjects
If TypeOf Objet.Object Is MSForms.TextBox Then
Nbre = Nbre + 1
ReDim Preserve TxtB(1 To Nbre)
Set TxtB(Nbre).MyCl = Objet.Object
End If

Next Objet
End Sub


Pourriez-vous m'aider svp?

Merci d'avance!
0