Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2016 Gérer un évènement sur un grand nombre de contrôles de même type d'un UserForm

Dudu2

XLDnaute Barbatruc
Bonjour,

J'ai 100 TextBoxes dans un UserForm.
Je voudrais gérer soit le _Enter soit le _DblClick sur tous ces contrôles pour y faire quelque chose de commun.
Pour éviter de déclarer 100 fois dans le code du UserForm le même évènement sur chacune des TextBoxes j'aimerais savoir s'il y a un autre possibilité, genre une classe dédiée.
Mais je ne suis pas très expert dans ce domaine et serais reconnaissant pour toute aide apportée sur la méthode.

Ci-joint un fichier avec 1 userForm de 3 TextBoxes comme base pour proposer un code qui ferait un simple MsgBox "Hello" sur un double-clic dans toutes les TextBoxes.
Merci par avance.
 

Pièces jointes

  • Classeur1.xlsm
    21.7 KB · Affichages: 7

sylvanu

XLDnaute Barbatruc
Supporter XLD
Bonjour Dudu,
En m'inspirant de ce fil : LIEN
La PJ contient :
Module de classe :
VB:
Public WithEvents TB As MSForms.TextBox
Private Sub TB_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    MsgBox "HELLO"
End Sub
Init userform:
Code:
Option Explicit
Dim TB() As New Classe1
Sub a()
    Dim c As Control, n
        For Each c In UserForm1.Controls
            If TypeName(c) = "TextBox" Then
                ReDim Preserve TB(n)
                Set TB(n).TB = c
                n = n + 1
            End If
        Next
    UserForm1.Show
End Sub
Mais le message apparait dès qu'on clic sur un textbox.
Avec TB_DblClick( il faut cliquer trois fois pour le message, la première fois pour sélectionner puis double clic.
Mais au moins ça fait avancer les choses, et vous et moi avons appris à utiliser un module de classe.
 

Pièces jointes

  • Classeur1 (10).xlsm
    19 KB · Affichages: 1

Dudu2

XLDnaute Barbatruc
Pas grave je peux contourner avec ton code en ajoutant un SetFocus.
VB:
Private Sub TB_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    TB.SetFocus
    MsgBox "HELLO"
End Sub
 

Eric C

XLDnaute Barbatruc
Bonjour le forum
Bonjour Dudu2, bonjour sylvanu

A peu près similaire - Sur un fichier de notre ami patricktoulon, que je salue au passage, une solution qui comme le dit notre ami sylvanu, oblige le user à cliquer une fois de plus pour obtenir le focus du contrôle.

VB:
Option Explicit

Public WithEvents TxtB As MSForms.TextBox
Dim cls(1 To 3) As New UserForm1


Private Sub CommandButton1_Click()
Unload Me
End Sub

Private Sub TxtB_DblClick(ByVal Cancel As MSForms.ReturnBoolean): MsgBox "coucou": End Sub
 
Private Sub UserForm_Activate()
Dim i As Byte
For i = 1 To 3: Set cls(i).TxtB = Me.Controls("TextBox" & i): Next
End Sub

Bonne après-midi à toutes & à tous
@+ Eric c
 

Pièces jointes

  • Click TxtB MsgBox.xlsm
    22.1 KB · Affichages: 2

Dudu2

XLDnaute Barbatruc
Merci @Eric C,
@patricktoulon a un manière particulière de faire ça sans module de classe avec un Dim cls(1 To 3) As New UserForm1. Je me souviens d'une discussion à ce propos et je sais pas trop ce que ça génère. Même si ça marche parfaitement.

Edit: cependant si cela instancie autant de UserForm1 que de Controls concernés, pour une centaine de Controls je me demande si la mémoire ne va pas en prendre un coup !
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Je publie les 2 méthodes (la standard fournie par @sylvanu, et la "@patricktoulon" fournie par@Eric C) sur le même modèle de code à toutes fins utiles.

Merci encore à vous deux !
 

Pièces jointes

  • Gérer des contrôles multiples avec un module de classe.xlsm
    27.4 KB · Affichages: 6
  • Gérer des contrôles multiples sans module de classe - Version patricktoulon.xlsm
    26.7 KB · Affichages: 5

patricktoulon

XLDnaute Barbatruc
re
bonjour
Edit: cependant si cela instancie autant de UserForm1 que de Controls concernés, pour une centaine de Controls je me demande si la mémoire ne va pas en prendre un coup !
@Dudu2
ça ne génère pas des userform ça instancie autant d'instance du module du userform c'est pas la même chose
avec un module classe tu fait la même chose
un module d'userform est un module classe avant tout
donc si il devait y avoir des soucis de mémoire ce serait pareil avec un module classe
 

Dudu2

XLDnaute Barbatruc
Une autre remarque qui n'a rien à voir avec la choucroute, peut-être plus à l'intention de @sylvanu dont j'avais repris le code.

J'ai bien ramé sur un module qui amène le menu système dans un UserForm sur la minimisation par code VBA à partir de Controls du UserForm. Et finalement, j'ai ENFIN pu déterminer que si on utilise:

- Control_MouseDown() le menu système en minimisé ne fonctionne plus.
=> il faut utiliser Control_MouseUp().

- Control_DblClick() direct le menu système en minimisé ne fonctionne plus.
=> il faut faire Cancel = True avant de minimiser.
 

Pièces jointes

  • VBA UserFormSystemMenu Minimiser Maximiser.xlsm
    34.7 KB · Affichages: 1

patricktoulon

XLDnaute Barbatruc
bonsoir @Dudu2
je te donne un raccourci
et par la même occasion je t’énumère tout les new long possible
pas besoins de connaitre le style de la fentre avant donc getwindowlong pifioufff
VB:
'---------------------------------
'Set the System Menu to a UserForm
'---------------------------------
Public Sub UserFormSystemMenu(UsfCaption As String)
    Dim hWndForm As Variant
    'Get UserForm Handle
    hWndForm = GetUsfHandle(UsfCaption)
    'Set the Alls basic Window styles
    SetWindowLong hWndForm, -16, &H94CF0080
    '&H94C80080  'Normal à l'origine (juste le bouton fermer)
    '&H94CA0080  'seulement le bouton reduire
    '&H94C90080  'seulement le bouton agrandir
    '&H94CB0080  'seulement les deux boutons agrandir & reduire
    '&H94CC0080  'seulement l'elasticité
    '&H94CE0080  'seulement l bouton reduire et l'élasticité
    '&H94CD0080  'seulement le bouton agranfir et l'élasticité
    '&H94CF0080  'LA TOTALE
    '&H94C00080  'pas de bouton dans la barre de titre
    '&H94080080  'pas de cadre pas de barre de titre
    '&H140F0101  'pas de barre de titre mais le cadre et elasticié
    '&H1010080   'barre de titre et cadre facon  Old Windows
End Sub

j'ajoute que pour la fonction showwindow il est intéressant de savoir ou d'appliquer un focus sur une autre fenêtre en fonction du mode choisi (je parle du mode 2 bien sur )
ShowWindow
Constante​
Valeur​
Définition​
SW_HIDE0Cache la fenêtre et en active une autre.
SW_MAXIMIZE3Agrandit la fenêtre.
SW_MINIMIZE6Réduit la fenêtre et active la prochaine (dans l'ordre des tâches windows).
SW_RESTORE9Active et affiche la fenêtre à sa taille et position initiales.
SW_SHOW5Active et affiche la fenêtre.
SW_SHOWMAXIMIZED3Active et agrandit la fenêtre.
SW_SHOWMINIMIZED2Active et réduit la fenêtre.
SW_SHOWNA8Identique à SW_SHOW sauf que la fenêtre n'est pas activée.
 

Dudu2

XLDnaute Barbatruc
Ok merci pour la liste.
Pour les constantes SW_ j'en avais essayé pas mal d'options, mais je pense que le blocage était dans le fait que soit en MouseDown() soit en DblClick() sans Cancel = True quelque chose était en attente quelque part qu'aucune des options possible de SW_ne pouvait débloquer.

La liste des options SW_ est ici:

Pour les WS_ tu as donné de combinaisons des constantes de ces listes:
Utile pour ne pas se prendre la tête avec les valeurs individuelles.
Merci
 

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…