XL 2021 Vba userform Controls.add

MNico1862

XLDnaute Nouveau
Bonjour,

J'utilise la méthode suivante pour crée des textbox :

Dim monUserForm As Object
Dim maTextBox As Object
Dim i As Integer
'Dim LastLig As Long


' Créer une instance du UserForm
Set monUserForm = Userform1

' Boucler pour ajouter 5 TextBox (ajustez selon vos besoins)
For i = 1 To 50
' Créer une instance de TextBox
Set maTextBox = monUserForm.Frame1.Controls.Add("Forms.comboBox.1", "comboBox" & i, True)

' Configurer la position et la taille de la TextBox
maTextBox.Left = 10
maTextBox.Top = 25 + (i - 1) * 24
maTextBox.Width = 100
maTextBox.Height = 25
maTextBox.List = Feuil1.Range("B2:B" & Feuil1.[A65000].End(xlUp).Row).Value
' Assigner un nom à la TextBox
maTextBox.Name = "Combobox" & i

Je voudrais savoir si il était possible maintenant lorsque une combobox change executer une macro car je peux pas faire combobox1.change() ?

Merci
 

Dranreb

XLDnaute Barbatruc
Bonsoir.
La prise en charge des évènements du contrôle ajouté dynamiquement doit être programmée dans un module de classe disposant en variable globale du contrôle, et y étant déclaré avec l'attribut WithEvents.
Notez que mon objet ComboBoxLiées serait tout à fait capable de prendre en charge une ComboBox créée dynamiquement, vu qu'il utilise déjà une classe support ComboBoxMmbr.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
je pige pas très bien pourquoi tu utiliserais
combobox1_change
ca serait plûtot matextbox_change()
sauf que tu n'a pas instancié de classe event
à la place de
Dim maTextBox As Object
c'est
public withevents matextbox as msforms.combobox
et pour l'instancier dans le activate
c'est
set monuserform.matextbox=me.combobox

oui sauf que tu en utilise 50
il ne peux pas avoir 2 object dans une instance de classe géré par le même event
c'est assez evident à comprendre non ?

bref ton code n'a ni queue ni tête

bref voici comment on le fait dans un userform
car un module userform est aussi un module classe
VB:
Public WithEvents comboboulboul As MSForms.ComboBox
Dim mesInstanceDeClasse(1 To 50) As New UserForm1 'creation des instance de classe  dans le userform
' car le userform est aussi un module classe

'un seul event pour les 50 comboboxs
Private Sub Comboboulboul_Change()
    MsgBox comboboulboul.Name & vbCrLf & comboboulboul.Value
End Sub

Private Sub UserForm_Activate()
    Dim i As Integer

    ' Boucler pour ajouter 5 TextBox (ajustez selon vos besoins)
    For i = 1 To 50
        ' Créer une combobox
        Set combo = Me.Frame1.Controls.Add("Forms.comboBox.1", "comboBox" & i, True)

        Set mesInstanceDeClasse(i).comboboulboul = combo 'on l'associe à  une instance  de classe
        ' Configurer la position et la taille de la TextBox
        With combo
            .Left = 10
            .Top = 25 + (i - 1) * 24
            .Width = 100
            .Height = 20
            ' Assigner un nom à la TextBox
            .Name = "Combobox" & i
            .List = Feuil1.Range("B2:B" & Feuil1.[A65000].End(xlUp).Row).Value
            
            Frame1.ScrollHeight = .Height + .Top ' ca fait beaucoup vaut mieux mettre une scroll a la frame
        End With
    Next

End Sub
 

MNico1862

XLDnaute Nouveau
re
je pige pas très bien pourquoi tu utiliserais
combobox1_change
ca serait plûtot matextbox_change()
sauf que tu n'a pas instancié de classe event
à la place de
Dim maTextBox As Object
c'est
public withevents matextbox as msforms.combobox
et pour l'instancier dans le activate
c'est
set monuserform.matextbox=me.combobox

oui sauf que tu en utilise 50
il ne peux pas avoir 2 object dans une instance de classe géré par le même event
c'est assez evident à comprendre non ?

bref ton code n'a ni queue ni tête

bref voici comment on le fait dans un userform
car un module userform est aussi un module classe
VB:
Public WithEvents comboboulboul As MSForms.ComboBox
Dim mesInstanceDeClasse(1 To 50) As New UserForm1 'creation des instance de classe  dans le userform
' car le userform est aussi un module classe

'un seul event pour les 50 comboboxs
Private Sub Comboboulboul_Change()
    MsgBox comboboulboul.Name & vbCrLf & comboboulboul.Value
End Sub

Private Sub UserForm_Activate()
    Dim i As Integer

    ' Boucler pour ajouter 5 TextBox (ajustez selon vos besoins)
    For i = 1 To 50
        ' Créer une combobox
        Set combo = Me.Frame1.Controls.Add("Forms.comboBox.1", "comboBox" & i, True)

        Set mesInstanceDeClasse(i).comboboulboul = combo 'on l'associe à  une instance  de classe
        ' Configurer la position et la taille de la TextBox
        With combo
            .Left = 10
            .Top = 25 + (i - 1) * 24
            .Width = 100
            .Height = 20
            ' Assigner un nom à la TextBox
            .Name = "Combobox" & i
            .List = Feuil1.Range("B2:B" & Feuil1.[A65000].End(xlUp).Row).Value
           
            Frame1.ScrollHeight = .Height + .Top ' ca fait beaucoup vaut mieux mettre une scroll a la frame
        End With
    Next

End Sub
est-il possible a la place de faire apparaitre une msg.
mettre la valeur 1 dans la textbox a coter.
J'ai rajouté une colonne mes de textbox
merci
 

Dranreb

XLDnaute Barbatruc
Bonsoir.
Créez plutôt un module de classe. L'habitude de @patricktoulon de prendre un exemplaire de l'UserForm tout entier chaque fois pour un seul contrôle que ne fait même pas partie de sa collection Controls est extrêmement incorrecte et absurde. Vous pourrez y prévoir une propriété pour son numéro, et une méthode dans votre UserForm pour le récupérer.
 

patricktoulon

XLDnaute Barbatruc
Bonsoir.
Créez plutôt un module de classe. L'habitude de @patricktoulon de prendre un exemplaire de l'UserForm tout entier chaque fois pour un seul contrôle que ne fait même pas partie de sa collection Controls est extrêmement incorrecte et absurde. Vous pourrez y prévoir une propriété pour son numéro, et une méthode dans votre UserForm pour le récupérer.
re
a ce que je comprends tu n'a pas compris la discussion que nous avions eu il y a un momment déja
alors je le repete
TOUT CE QUE TU PEUX FAIRE DANS UN MODULE CLASSE POUR UN CONTROLS TU PEUX LE FAIRE DANS UN USERFORM exactement de la même maniere
L'habitude de @patricktoulon de prendre un exemplaire de l'UserForm tout entier chaque fois pour un seul contrôle
et pour info quand tu classe x controls tu instancie x exemplaire de classe
en gros c'est exactement et strictement la même chose
 

Dranreb

XLDnaute Barbatruc
@MNico1862, rappelez vous que seuls dans des modules objets peuvent être pris en charge les évènements d'autre objets. Je dis ça parce qu'il n'a pas l'air évident que le code que vous citez dans votre 1er message soit dans un tel module.
Par ailleurs, pourquoi en voudriez vous en créer des dizaines ?
J'ai aussi l'impression que vous feriez mieux de n'en utiliser qu'une seule marchant de concert avec une ListBox.
Exemple de code pour l'UserForm :
VB:
Option Explicit
Private Sub UserForm_Initialize()
   CBxArticle.List = Feuil1.Range("B2:B" & Feuil1.[B65000].End(xlUp).Row).Value
   LBxPanier.ColumnCount = 2
   CBnEntrée.Default = True
   End Sub
Private Sub CBnEntrée_Click()
   Dim L As Integer, TLBx()
   If CBxArticle.MatchFound Then
      If Not IsNumeric(TBxQté.Text) Then TBxQté.SetFocus: Exit Sub
      L = LBxPanier.ListCount: LBxPanier.AddItem ""
      LBxPanier.List(L, 0) = CBxArticle.Text
      LBxPanier.List(L, 1) = TBxQté.Text
      CBxArticle.Text = ""
      TBxQté.Text = ""
   ElseIf LBxPanier.ListCount > 0 Then
      TLBx = LBxPanier.List
      For L = 0 To UBound(TLBx, 1): TLBx(L, 1) = CDbl(TLBx(L, 1)): Next L
      Feuil1.Range("D2:E15").ClearContents
      Feuil1.Range("D2").Resize(LBxPanier.ListCount, 2).Value = TLBx
      LBxPanier.Clear
      Me.Hide
      End If
   End Sub
Private Sub LBxPanier_Click()
   Dim L As Integer
   L = LBxPanier.ListIndex
   CBxArticle.Text = LBxPanier.List(L, 0)
   TBxQté.Text = LBxPanier.List(L, 1)
   LBxPanier.ListIndex = -1
   LBxPanier.RemoveItem L
   End Sub
 
Dernière édition:

Discussions similaires

Réponses
2
Affichages
438

Statistiques des forums

Discussions
313 309
Messages
2 097 030
Membres
106 812
dernier inscrit
Excellou74