IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Procédure liée à un TextBox créé dynamiquement [XL-2016]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Directeur technique
    Inscrit en
    Août 2018
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Août 2018
    Messages : 84
    Par défaut Procédure liée à un TextBox créé dynamiquement
    Bonjour,

    Je travail en simultané sur 2 userform. Le premier comprend une listbox avec des articles et des prix unitaires (PU). Le second (Devis) comprend un multipage dans lequel j'incère des lignes dynamiquement lors d'un double click sur un article de la listbox. Je crée donc une série de textbox avec, pour le sujet qui m'intéresse Quantité (TxtQte), Prix Unitaire (TxtPU) et Total (TxtTotal). Cette partie là fonctionne très bien.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    Dim Tqte As Control, Tpu As Control, Ttot As Control
    If T = 0 Then T = 24
      If I = 0 Then I = 1
          With UsfDevis.MultiPage1.Pages(1).Controls
          Set Tqte = .Add("Forms.TextBox.1")
          Set Tpu = .Add("Forms.TextBox.1")
          Set Ttot = .Add("Forms.TextBox.1")
          With Tqte
            .Name = "TxtQte" & I: .Left = 348: .Top = T: .Height = 18: .Width = 30
            .Value = UsfDevis.TxtNbreJour.Value
          End With
          With Tpu
            .Name = "TxtPU" & I: .Left = 390: .Top = T: .Height = 18: .Width = 42
            .Value = ListBox1.List(ListBox1.ListIndex, 2)
          End With
          With Ttot
            .Name = "TxtTotal" & I: .Left = 444: .Top = T: .Height = 18: .Width = 60
            .Value = ListBox1.List(ListBox1.ListIndex, 2) * Tqte.Value
          End With
          I = I + 1
          T = T + 24
    Les quantité, PU et Total sont reportés ainsi dans UsfDevis. A l'aide de msgbox j'ai vérifié les noms des textbox créées TxtQte1, TxtQte2 etc... Tout fonctionne bien.
    L'utilisateur va avoir besoin de temps en temps de modifier soit la quantité, soit le Prix Unitaire. J'ai donc créé une procédure dans UsfDevis pour traiter ce cas de figure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Private Sub TxtQte1_Change()
      TxtTotal1.Value = TxtQte1 * TxtPU1
    End Sub
    Private Sub TxtPU1_Change()
      TxtTotal1.Value = TxtQte1.Value * TxtPU1.Value
    End Sub
    Et c'est là que ça coince. Si je change la quantité, le total ne change pas
    si je change le PU, le total ne change pas non plus.

    La question est: Qu'est ce que j'ai mal fait? ca me paraissait pourtant à ma portée.

    Merci d'avance

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    Bonjour,

    Et c'est là que ça coince. Si je change la quantité, le total ne change pas
    si je change le PU, le total ne change pas non plus.
    Il te faut utiliser un module de classe !

  3. #3
    Membre confirmé
    Homme Profil pro
    Directeur technique
    Inscrit en
    Août 2018
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Août 2018
    Messages : 84
    Par défaut
    Bonjour Theze
    Pourquoi?
    Je ne comprends pas

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    Quand tu crée un ou plusieurs contrôles dynamiques il te faut utiliser un module de classe afin de lier les événements que tu veux gérer aux contrôles. Je suis sur mon IPhone et en vacances donc, je ne peux pas te pondre un code mais ici, tu trouveras pleins d’exemples !

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonsoir,
    Citation Envoyé par Floyd-44 Voir le message
    Bonjour Theze
    Pourquoi?
    Je ne comprends pas
    parce que c'est comme ça qu'il faut faire!
    Fichiers attachés Fichiers attachés
    Dernière modification par Invité ; 07/09/2018 à 19h54.

  6. #6
    Membre confirmé
    Homme Profil pro
    Directeur technique
    Inscrit en
    Août 2018
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Août 2018
    Messages : 84
    Par défaut
    Bonjour Theze, dysorthographie,

    Quand tu crée un ou plusieurs contrôles dynamiques il te faut utiliser un module de classe afin de lier les événements que tu veux gérer aux contrôles
    parce que c'est comme ça qu'il faut faire!
    Merci pour le fichier qui m'a bien aidé à la compréhension du principe général. J'ai téléchargé, imprimé et bien lu et relu le cours de Pierre Fauconnier "Création et utilisation de classes personnalisées" Il faut quand même être averti pour être à l'aise avec ce sujet.
    En clair, le problème que j'ai par rapport au code de dysorthographie est : comment différencier les textbox?
    Dans le module de classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    Private WithEvents Tb As MSForms.TextBox
    Private ctrName As String
     
    Public Property Let Objet(value As Object)
    ctrName = TypeName(value)
    Select Case ctrName
        Case "TextBox": Set Tb = value
     End Select
    End Property
    Public Property Get Objet() As Object
    Select Case ctrName
        Case "TextBox": Set Objet = Tb
     End Select
    End Property
    Private Sub Tb_Change()
    MsgBox Tb
    End Sub
    Dans Userform1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    Dim Cs(2) As New TheControl, I As Integer, T As Integer
     
    Private Sub UserForm_Initialize()
    If T = 0 Then T = 24
      If I = 0 Then I = 1
          With Me.MultiPage1.Pages(0).Controls
           Cs(0).Objet = .Add("Forms.TextBox.1")
           Cs(1).Objet = .Add("Forms.TextBox.1")
           Cs(2).Objet = .Add("Forms.TextBox.1")
          With Cs(0).Objet
            .Name = "TxtQte" & I: .Left = 348: .Top = T: .Height = 18: .Width = 30
            '.value = Me.TxtNbreJour.value
          End With
          With Cs(1).Objet
            .Name = "TxtPU" & I: .Left = 390: .Top = T: .Height = 18: .Width = 42
           ' .value = ListBox1.List(ListBox1.ListIndex, 2)
          End With
          With Cs(2).Objet
            .Name = "TxtTotal" & I: .Left = 444: .Top = T: .Height = 18: .Width = 60
           ' .value = ListBox1.List(ListBox1.ListIndex, 2) * Tqte.value
          End With
          I = I + 1
          T = T + 24
          End With
    End Sub
    Cela fonctionne bien, 3 textbox sont créees et j'ai le msgbox qui affiche la valeur saisie si j'apporte une modification dans l'une ou l'autre.
    En revanche, je voudrais que le msgbox ne s'affiche que sur une des 3 textbox. Et là, je galère dur…!
    Comment faire pour les différencier…?

    Merci pour l'aide

  7. #7
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Tb_Change()
    If Tb.Name like "TxtQte*" then MsgBox Tb
    End Sub

  8. #8
    Membre confirmé
    Homme Profil pro
    Directeur technique
    Inscrit en
    Août 2018
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Août 2018
    Messages : 84
    Par défaut
    J'ai honte...
    J'ai tout fait sauf ca

  9. #9
    Invité
    Invité(e)
    Par défaut
    bien sur il faut vérifier le format numérique de tous les termes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Private Sub Tb_Change()
    Dim i as integee
    If Tb.Name like "TxtQte*" then 
        i=cint(split(Tb.Name,"TxtQte")(1))
        Tb.parent.contorols("TxtTotal" & i)=tb * Tb.parent.contorols("TxtPU" & i)
    End Sub

  10. #10
    Membre confirmé
    Homme Profil pro
    Directeur technique
    Inscrit en
    Août 2018
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Août 2018
    Messages : 84
    Par défaut
    J'ai moins honte d'un coup...😀
    Merci pour le coup de main.

  11. #11
    Membre confirmé
    Homme Profil pro
    Directeur technique
    Inscrit en
    Août 2018
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Août 2018
    Messages : 84
    Par défaut
    Bonjour,

    Sur cette ligne :" Tb.Parent.Controls("TxtTotal" & I) = Tb * Tb.Parent.Controls("TxtPU" & I)"
    J'ai ça comme message d'erreur:
    Nom : Sans titre.jpg
Affichages : 208
Taille : 8,6 Ko

    Avec ce code après avoir bien vérifié le Tb.Name
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Private Sub Tb_Change()
    Dim I As Integer
    If Tb.Name Like "TxtQte*" Then
        I = CInt(Split(Tb.Name, "TxtQte")(1))
        Tb.Parent.Controls("TxtTotal" & I) = Tb * Tb.Parent.Controls("TxtPU" & I)
    End If
    End Sub
    J'ai aussi remarqué que lorsque je tape "Tb." il ne me propose, ni Name, ni Controls, ni parent
    Nom : Sans titre.jpg
Affichages : 216
Taille : 12,8 Ko
    Bref je suis perdu

  12. #12
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
     
     
    Dim Cs() As New TheControl
     
    Private Sub NewControl_Click()
        Static I As Integer
        ReDim Preserve Cs(I)
        With Me.MultiPage1.Pages(0).Controls
            Set Cs(I).TxtQte = .Add("Forms.TextBox.1")
            Set Cs(I).TxtPU = .Add("Forms.TextBox.1")
            Set Cs(I).TxtTotal = .Add("Forms.TextBox.1")
            With Cs(I)
                If I = 0 Then
                    .TxtQte.Name = "TxtQte" & I: .TxtQte.Left = 348: .TxtQte.Top = 0: .TxtQte.Height = 18: .TxtQte.Width = 30: '.value = Me.TxtNbreJour.value
                Else
                    .TxtQte.Name = "TxtQte" & I: .TxtQte.Left = 348: .TxtQte.Top = Cs(I - 1).TxtQte.Top + Cs(I - 1).TxtQte.Height: .TxtQte.Height = 18: .TxtQte.Width = 30
                End If
            .TxtPU.Name = "TxtPU" & I:   .TxtPU.Left = 390:   .TxtPU.Top = .TxtQte.Top:   .TxtPU.Height = 18:   .TxtPU.Width = 42
            .TxtTotal.Name = "TxtTotal" & I: .TxtTotal.Left = 444: .TxtTotal.Top = .TxtQte.Top: .TxtTotal.Height = 18: .TxtTotal.Width = 60
            I = I + 1
            End With
        End With
    End Sub
     
     
    Private Sub UserForm_Initialize()
    NewControl_Click
    End Sub
    Code TheControl : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     Public WithEvents TxtQte As MSForms.TextBox
    Public WithEvents TxtPU As MSForms.TextBox
    Public WithEvents TxtTotal As MSForms.TextBox
    Private ctrName As String
     
     
     
    Private Sub TxtQte_Change()
     If TxtQte <> "" And TxtPU <> "" Then TxtTotal = Val(Replace(TxtQte, ",", ".")) * Val(Replace(TxtPU, ",", ".")) Else TxtTotal = ""
    End Sub
     
     
    Private Sub TxtPU_Change()
     TxtQte_Change
    End Sub
    Fichiers attachés Fichiers attachés

  13. #13
    Membre confirmé
    Homme Profil pro
    Directeur technique
    Inscrit en
    Août 2018
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Août 2018
    Messages : 84
    Par défaut
    Bonjour,

    J'ai posé ça sur mon projet et ça marche très très bien.
    J'avais essayé de déninir les txtbox dans le module de classe Public WithEvents aussi mais je n'arrivais pas à m'en sortir.

    J'ai un peu voire beaucoup de mal à comprendre la notion de redim malgré la lecture et aussi de la condition If que tu emploies. (If I = 0 then...) Je n'arrive pas à saisir pourquoi ca ne marche pas avec If I = 0 then I = 1 par exemple

    En tout cas merci beaucoup, c'est parfait

  14. #14
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     'Dim Cs()AsNew TheControl fait référence à un tableau vide de la classe TheControl
    Dim Cs() As New TheControl, I As Integer
     
    Private Sub NewControl_Click()
    'je redimentionne mon table et préserve les valeurs existante
        ReDim Preserve Cs(I)
        With Me.MultiPage1.Pages(0).Controls
            Set Cs(I).TxtQte = .Add("Forms.TextBox.1")
            Set Cs(I).TxtPU = .Add("Forms.TextBox.1")
            Set Cs(I).TxtTotal = .Add("Forms.TextBox.1")
            With Cs(I)
                If I = 0 Then 'si i = 0 premère instance de la classe je defini TxtQte.Top =0 si nom je prends le top du TxtQte.Top précédent et j'y ajout l'espacement vertical
                '.TxtQte.Top = Cs(I - 1).TxtQte.Top + Cs(I - 1).TxtQte.Height
                    .TxtQte.Name = "TxtQte" & I: .TxtQte.Left = 348: .TxtQte.Top = 0: .TxtQte.Height = 18: .TxtQte.Width = 30: '.value = Me.TxtNbreJour.value
                Else
                    .TxtQte.Name = "TxtQte" & I: .TxtQte.Left = 348: .TxtQte.Top = Cs(I - 1).TxtQte.Top + Cs(I - 1).TxtQte.Height: .TxtQte.Height = 18: .TxtQte.Width = 30
                End If
                'jaligne mes autre contron sur .TxtQte.Top
            .TxtPU.Name = "TxtPU" & I:   .TxtPU.Left = 390:   .TxtPU.Top = .TxtQte.Top:   .TxtPU.Height = 18:   .TxtPU.Width = 42 '.TxtPU.Top = .TxtQte.Top
            .TxtTotal.Name = "TxtTotal" & I: .TxtTotal.Left = 444: .TxtTotal.Top = .TxtQte.Top: .TxtTotal.Height = 18: .TxtTotal.Width = 60 ' .TxtTotal.Top = .TxtQte.Top
            I = I + 1
            End With
        End With
    End Sub
    
    
    Private Sub UserForm_Initialize()
    NewControl_Click 'jinitialise la permière linge de control!
    End Sub

  15. #15
    Membre confirmé
    Homme Profil pro
    Directeur technique
    Inscrit en
    Août 2018
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Août 2018
    Messages : 84
    Par défaut Remerciements
    Message envoyé en privé sans succès

    Bonjour et Bonne année à tous les deux,

    Je voulais vous remercier tous les deux particulièrement pour votre aide sur le projet (devis, factures, clients etc..) que j'ai offert à ma petite sœur pour noël. Il marche très bien et ma sœur est ravie.

    Merci à Pierre pour le cours de Tennis, excellent pour apprendre. En plus, j'ai même compris ton histoire sur les Range(x)

    Merci à Dysorthographie pour la leçon sur l'intégration de textes en sql et le module de classe. Cette dernière partie est encore bien complexe pour moi. J'arrive à ajouter les rangs de textbox dynamiquement et à leur associer des procédures (Qté * Prix = Total) mais pas encore à faire la somme de toutes les texbox total. J'ai donc mis cette partie là de côté.

    Merci encore pour votre aide et pour ma sœur

    Matthieu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 23/02/2016, 16h46
  2. [C#] Récupérer le texte de textBox créées dynamiquement
    Par cyllix dans le forum Windows Forms
    Réponses: 4
    Dernier message: 19/06/2006, 11h45
  3. Réponses: 1
    Dernier message: 25/04/2006, 16h22
  4. [VBA-E] Retrouver un textbox créé dynamique
    Par wind_vinch dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 14/10/2005, 12h51
  5. Réponses: 2
    Dernier message: 25/06/2005, 17h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo