Générer plusieurs ListBox dynamiquement depuis une ListeBox

taratata

XLDnaute Junior
Bonjour,

Lors de la sélection d'une des lignes d'une ListeBox, je génère sur le formulaire une TextBox.
Cela fonctionne bien.

Par contre, la position en hauteur TOP est identique à la valeur de l'index du select de la ligne de la listBox

Mon souhait est peu importe la position de la ligne sélectionnée dans la listbox Créera une TextBox sur la 1er ligne prévue à cette effet dans le formulaire
la seconde sélection créera le TextBox en dessous de la 1er TextBox. etc...

Il semble que ce soit cette variable qui faut incrémenter différemment --> .Top = 130 + (j) * 15 --> mais diférents test ne donnent rien

voici le code pour plus de clarté

VB:
Private Sub ListBox_ARO_DblClick(ByVal Cancel As MSForms.ReturnBoolean)

Dim i As Integer
[B]Dim j As Integer[/B]
Dim ctrl As Control

    For i = 0 To ListBox_ARO.ListCount - 1
[B]j = 1[/B]
        If ListBox_ARO.Selected(i) Then
[B]j = j + 1[/B]
            'Label Nom Arôme
            Set ctrl = Me.Controls.Add("Forms.Label.1")
            With ctrl
                .Height = 12
                .Width = 234
                .Left = 24
                .Top = 130 + ([B]j[/B]) * 15
                .Caption = Select_Nom_Arome & ListBox_ARO.List(i, 2)
                .Name = "Lab_" & Select_Nom_Arome & ListBox_ARO.List(i, 2)
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
           
            ' TextBox Dosage Arôme
            Set ctrl = Me.Controls.Add("Forms.TextBox.1")
            With ctrl
                .Height = 18
                .Width = 24
                .Left = 264
                .Top = 126 + (j) * 21
                .Name = "TB_" & Select_Nom_Arome & ListBox_ARO.List(i, 2)
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
           
            'Label symbôle %
            Set ctrl = Me.Controls.Add("Forms.Label.1")
            With ctrl
                .Height = 12
                .Width = 12
                .Left = 289
                .Top = 130 + (j) * 15
                .Caption = "%"
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
           
            ' TextBox Quantité dû au dosage Arôme
            Set ctrl = Me.Controls.Add("Forms.TextBox.1")
            With ctrl
                .Height = 18
                .Width = 30
                .Left = 310
                .Top = 126 + (j) * 21
                .Name = "TB_Q_" & Select_Nom_Arome & ListBox_ARO.List(i, 2)
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
           
            'Label ml
            Set ctrl = Me.Controls.Add("Forms.Label.1")
            With ctrl
                .Height = 12
                .Width = 12
                .Left = 342
                .Top = 130 + (j) * 15
                .Caption = "ml"
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
        End If
   
    Next i

    ' lecture du nom de control type TextBox & Label
    Dim Ob As Control
    For Each Ob In Me.Controls
   
        If TypeOf Ob Is MSForms.TextBox Then
           ' MsgBox Ob.Name
            Debug.Print Ob.Name
        End If
        If TypeOf Ob Is MSForms.label Then
           ' MsgBox Ob.Name
            Debug.Print Ob.Name
        End If
    Next


End Sub



merci de votre temps
 

taratata

XLDnaute Junior
Le TextBox % doit être remplie par l'utilisateur pour donner une quantité ml dans la TextBox suivante. Cette quantité devra être vérifiée/comparée par rapport à la quantité issue de l'article sélectionné dans la ListeBox.

La variable j est supprimée. Lors du double clic, les contrôles sont générés selon i.
Donc si je double click sur la 3ème ligne, les contrôles est généré en 3ème position sur le formulaire.

le but, par exemple :
la 3ème ligne sélection, affichée en 1er position
la 1er. ligne sélection, affichée en 2ème position
la 5ème ligne sélection, affichée en 3ème position

puis le nombre de sélection soit limité à 4 maximum

voici le code qui fonctionne comme je le souhaite. je pense que des amélioration peuvent être faites.

VB:
Private Sub ListBox_ARO_DblClick(ByVal Cancel As MSForms.ReturnBoolean)

Dim i As Integer
Dim ctrl As Control

' --> Limiter le nombre de sélection
Static nb As Integer
Dim choisi As Integer
Dim max As Integer
max = 4                     ' nombre maxi de sélections autorisées

choisi = ListBox_ARO.ListIndex

If ListBox_ARO.Selected(choisi) = False Then nb = nb - 1: Exit Sub
If nb >= max Then ListBox_ARO.Selected(choisi) = False: MsgBox "   " & max & " arômes autorisés ...", vbInformation, "Stunam! Vap"
' MsgBox "nb ?   : " & nb    ' commence par Zéro
nb = nb + 1


' --> Génère des controles dynamiquement dans une frame
    For i = 0 To ListBox_ARO.ListCount - 1

        If ListBox_ARO.Selected(i) Then

            'Label Nom Arôme
            Set ctrl = Me.Frame1.Controls.Add("Forms.Label.1")
            With ctrl
                .Height = 12
                .Width = 234
                .Left = 24
                .Top = 6 + nb * 21  '.Top = 10 + nb * 21
                .Caption = Select_Nom_Arome & ListBox_ARO.List(i, 2)
                .Name = "Lab_" & Select_Nom_Arome & ListBox_ARO.List(i, 2)
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
            
            ' TextBox Dosage Arôme
            Set ctrl = Me.Frame1.Controls.Add("Forms.TextBox.1")
            With ctrl
                .Height = 18
                .Width = 24
                .Left = 264
                .Top = nb * 21  '.Top = 4 + nb * 21
                .Name = "TB_D_" & Select_Nom_Arome & ListBox_ARO.List(i, 2)
                .object.Value = ""
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
            
            'Label symbôle %
            Set ctrl = Me.Frame1.Controls.Add("Forms.Label.1")
            With ctrl
                .Height = 12
                .Width = 12
                .Left = 289
                .Top = 6 + nb * 21        '.Top = 10 + nb * 21
                .Caption = "%"
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
            
            ' TextBox Quantité dû au dosage Arôme
            Set ctrl = Me.Frame1.Controls.Add("Forms.TextBox.1")
            With ctrl
                .Height = 18
                .Width = 30
                .Left = 310
                .Top = nb * 21               '.Top = 4 + nb * 21
                .Name = "TB_Q_" & Select_Nom_Arome & ListBox_ARO.List(i, 2)
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
            
            'Label ml
            Set ctrl = Me.Frame1.Controls.Add("Forms.Label.1")
            With ctrl
                .Height = 12
                .Width = 12
                .Left = 342
                .Top = 6 + nb * 21              '.Top = 10 + nb * 21
                .Caption = "ml"
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10
            End With
            ' Dimensionnement automatique de la Frame1
            If nb = 0 Then
                Me.Frame1.Height = 42
                'MsgBox "0 - La ligne sélectionnée " & ListBox_ARO.List(i, 2) & " à le numéro ListIndex : " & ListBox_ARO.ListIndex
            ElseIf nb = 1 Then
                Me.Frame1.Height = 62
                'MsgBox "1 - La ligne sélectionnée " & ListBox_ARO.List(i, 2) & " à le numéro ListIndex : " & ListBox_ARO.ListIndex
            ElseIf nb = 2 Then
                Me.Frame1.Height = 82
                'MsgBox "2 - La ligne sélectionnée " & ListBox_ARO.List(i, 2) & " à le numéro ListIndex : " & ListBox_ARO.ListIndex
            ElseIf nb = 3 Then
                Me.Frame1.Height = 122
                'MsgBox "3 - La ligne sélectionnée " & ListBox_ARO.List(i, 2) & " à le numéro ListIndex : " & ListBox_ARO.ListIndex
            End If
        End If
    
    Next i

    ' -->  Identification du nom des controles type TextBox & Label
    Dim Ob As Control
    For Each Ob In Me.Controls
    
        If TypeOf Ob Is MSForms.TextBox Then
           ' MsgBox Ob.Name
            Debug.Print Ob.Name
        End If
        If TypeOf Ob Is MSForms.label Then
           ' MsgBox Ob.Name
            Debug.Print Ob.Name
        End If
    Next
    
    ' -->  Identification Numéro ListIndex de la sélection
    For i = 0 To ListBox_ARO.ListCount - 1
         If ListBox_ARO.Selected(i) = True Then
            ' 2 est la 3éme colonne du tableau Arôme - Numéro de l'index
            'MsgBox "La ligne sélectionnée " & ListBox_ARO.List(i, 2) & " à le numéro ListIndex : " & ListBox_ARO.ListIndex
         End If
    Next i


End Sub
 

taratata

XLDnaute Junior
voici le fichier

maintenant, je cherche à gérer automatiquement les valeurs entrées dans les TextBox %, si c'est bine du numérique et pas inférieur ou égal à zéro.

je sais faire sur un TextBox en mode normal.
En dynamique j'ai testé en passant avec un bouton (pas très heureux)

voici la code pour ce problème
VB:
Private Sub CommandButton1_Click()

    'uniquement des chiffres
    If Not IsNumeric(Me.Frame1.TB_D_1) And Me.Frame1.TB_D_1 <> "" Then
        MsgBox "introduire uniquement un valeur numérique!", vbExclamation, "Stunam! Vap"
        Me.Frame1.TB_D_1.Value = ""
    End If
    'interdit valeur inférieur ou égal à zéro
    If IsNumeric(Me.Frame1.TB_D_1.Value) Then
       'Me.Frame1.TB_Q_1.Value = Text_Q_Fiole.Value * (Me.Frame1.TB_D_1.Value / 100)
        If Val(Me.Frame1.TB_D_1.Value) <= 0 Then
            MsgBox "introduire uniquement un valeur entier!", vbExclamation, "Stunam! Vap"
            Me.Frame1.TB_Q_1.Value = ""
            Me.Frame1.TB_D_1.Value = ""
        Else
            Me.Frame1.TB_Q_1.Value = Text_Q_Fiole.Value * (Me.Frame1.TB_D_1.Value / 100)
        End If
        
    End If
    
'MsgBox Me.Text_Q_Fiole.Value
MsgBox "TB_D_1   =  " & Me.Frame1.TB_D_1.Value
'MsgBox "TB_D_2   =  " & Me.Frame1.TB_D_2.Value
'MsgBox "TB_D_3   =  " & Me.Frame1.TB_D_3.Value
'MsgBox "TB_D_4   =  " & Me.Frame1.TB_D_4.Value

'Me.Frame1.TB_Q_1.Value = Text_Q_Fiole.Value * (Me.Frame1.TB_D_1.Value / 100)
'Me.Frame1.TB_Q_2.Value = Text_Q_Fiole.Value * (Me.Frame1.TB_D_2.Value / 100)
'Me.Frame1.TB_Q_3.Value = Text_Q_Fiole.Value * (Me.Frame1.TB_D_3.Value / 100)
'Me.Frame1.TB_Q_4.Value = Text_Q_Fiole.Value * (Me.Frame1.TB_D_4.Value / 100)
End Sub
 

Pièces jointes

  • 1 - TEST.xlsm
    545.5 KB · Affichages: 8

Staple1600

XLDnaute Barbatruc
Bonsoir

J'ai voulu tester ton classeur
Erreur sur cette procédure quand je clique sur le bouton Valider
Code:
Sub Suff_ARO(New_Suff)
    ' No. Article - Incémentation Suffixe ARO
    New_Suff = Sheets("Config").Range(ID_Suff).Value
End Sub
Erreur 1004
 

taratata

XLDnaute Junior
il ne faut pas tenir compte du bouton "Valider".
Il faut remplir E-liquid final , une fois avoir double clic sur 4 max arômes, indiquer les champs dosage %
puis cliquer "CommandButton".

J'aimerai ne pas passer par un bouton.
Poser la condition sur TextBox % --> Si valeur NoT isnumric et non Zéro et Non négative.

Comme je suis débutant, il semble qu'il faille créer une classe collection de l'objet TextBox%

de l'aide?
 

taratata

XLDnaute Junior
j'ai mis en place une classe sur l'objet TextBox

L'événement ne fonctionne que sur le dernier TextBox généré





VB:
Option Explicit

Private Sub ListBox_ARO_DblClick(ByVal Cancel As MSForms.ReturnBoolean)

Dim obj As Control
Dim Cl As Nom_Cl
Set Collect = New Collection

...

 Set obj = Me.Frame1.Controls.Add("Forms.TextBox.1")
            With obj
                .Height = 18
                .Width = 24
                .Left = 264
                .Top = nb * 21
                .Name = "TB_D_" & nb
                '.object.text = .Name            ' Affiche le Nom du control dans la TextBox
                .object.Value = ""
                .TabIndex = i
                .Font.Name = "Verdana"
                .Font.size = 10

            End With
            Set Cl = New Nom_Cl
            Set Cl.TBox = obj
            Collect.Add Cl
            
            ...
            End Sub

Code:
dans le module

Option Explicit
Public Collect As Collection

Code:
dans le classe nommée Nom_Cl

Option Explicit

Public WithEvents TBox As MSForms.TextBox

Private Sub TBox_Change()

    'affiche nom & valeur de l'objet
    MsgBox "Nom de l'objet TextBox  " & Me.TBox.Name & vbCrLf _
           & "Valeur contenue  " & Me.TBox.Value

    'uniquement des chiffres
    If Not IsNumeric(Me.TBox) And Me.TBox <> "" Then
        MsgBox "introduire uniquement un valeur numérique!", vbExclamation, "Stunam! Vap"
        Me.TBox.Value = ""
    End If
    
End Sub
 

Pièces jointes

  • 2 - TEST.xlsm
    548.8 KB · Affichages: 4

Bebere

XLDnaute Barbatruc
bonjour
Tarata
il faut déclarer nb en tête de code,après option explicit
fait un code module de classe keypress
listbox liststyle sur option ,le code aurait été plus simple
 

Pièces jointes

  • 2 - TEST.xlsm
    57.2 KB · Affichages: 6

taratata

XLDnaute Junior
Merci bebere

ça fonctionne bien
j'ai remplacer la condition "uniquement nombre" par

VB:
'Uniquement des nombres
If IsNumeric(Chr(KeyAscii)) Then KeyAscii = KeyAscii Else: KeyAscii = 0

je n'arrive pas à faire passer la valeur indiquée dans le textbox "%" automatiquement dans le textbox "ml".
j'y arrive par un clique bouton BT2.

je souhaite que lors de la saisie du textbox "%," le résultat s'affiche automatiquement dans le textbox "ml"
(on se comprends bien - je ne parle pas des label % et ml)

J'ai essayé de place dans la classe sous
Private Sub Tbox_Change()
End Sub

mais rien y fait.

une idée? merci
 

Pièces jointes

  • 2 - TEST-C.xlsm
    54.6 KB · Affichages: 3

Bebere

XLDnaute Barbatruc
bonsoir
Taratata module1 déclaré fr as frame,initialisé ds userform_initialise
sert ds le module de classe
explication dans userform
je pense que tu peux supprimer le controle à l'addition de label ou textbox
 

Pièces jointes

  • 2 - TEST-C.xlsm
    54.2 KB · Affichages: 3

taratata

XLDnaute Junior
Bonjour,

si j'ai bien compris le concept de classe, il faut

1 - Créer un objet collection permettant d’accéder aux objets référencé dans la classe
elle est déclarée comme ceci :
Public Collect As Collection

2 - Déclaration de la classe étant un gabarit contenant les propriétés de l'objet cible
' instance de la classe Class1
' instanciation est la création d'un objet à partir d'une classe.
Dim Tbox(1 To 4) As New Class1

3 - On associe l'objet à la classe

Dim obj0 As Control

' TextBox
Set obj0 = Me.Frame1.Controls.Add("Forms.TextBox.1")
With obj0
...
End With
Set Tbox(nb).Tbox = Controls("TB_D_" & nb)

4 - Modules de Classe

On y définit les propriétés de l'objet
 

taratata

XLDnaute Junior
bonjour,

Je n'arrive pas à faire la liaison avec la ligne sélectionnée de listebox pour vérifier, en tant réelle, si la quantité en Listebox est suffisante par rapport la la quantité de besoin "ml"

j'ai essayé avec Public variable as .... dans le Formulaire ou Module, en vain.

à moins qu'il faille mettre le No.art puis Quantité Disponible de la table en tant que classe


merci
 

Pièces jointes

  • _13.jpg
    _13.jpg
    3.4 KB · Affichages: 20
  • _14.jpg
    _14.jpg
    6 KB · Affichages: 20
  • 2 - TEST-Ca_1.xlsm
    64.7 KB · Affichages: 8

taratata

XLDnaute Junior
Bonjour Bebere,

La manœuvre du formulaire est de
- Etape A -
1 - sélectionner un maximum de 4 fiole d'arômes
2 - pour chaque sélectionner, indiquer le dosage "%" donnant en direct la quantité "ml"
la valeur "%" peut être décimal "ex: 2.5 ou 0.75", se qui est répercuté sur la valeur "ml"

3 - toujours en direct, la quantité "ml" est comparée (strictement inférieur) à la quantité de la fiole de l'arôme sélectionnée


- Etape B -
1 - La quantité "E-Liquide final" est comparée (strictement inférieur) avec la quantité de la base nicotinée

- Etape C -
Tant que c'est vérification, le bouton "Validation" est grisé.


j'ai besoin de connaitre l'écriture VBA pour la comparaison de la valeur du TextBox TB_Q_(i) avec la valeur Quantité de la sélection correspondante de la ListeBox.
 

Bebere

XLDnaute Barbatruc
bonjour
Tarata voilà un exemple
QD_Arome variable public
QD_Arome = ListBox_ARO.List(choisi, 15)'dans la listb
mis un msgbox si q<total
tu te rends compte que le msgbox dans listbox apparait à chaque caractère entre dans dosage
Private Sub Tbox_Dosage_Change()
Dim i As Byte

If Creation_Liquide.Text_Q_Fiole <> "" Then

i = Mid(Tbox_Dosage.Name, 6)

'uniquement des chiffres
If Not IsNumeric(fr.Controls("TB_D_" & i)) And fr.Controls("TB_D_" & i) <> "" Then
MsgBox "introduire uniquement un valeur numérique!", vbExclamation, "Stunam! Vap"
fr.Controls("TB_D_" & i) = ""
End If

If fr.Controls("TB_D_" & i) <> "" And fr.Controls("TB_D_" & i) <> 0 Then
fr.Controls("TB_Q_" & i) = Format(CDec((Tbox_Dosage / 100) * Creation_Liquide.Text_Q_Fiole.Value), "0.00")
End If
If fr.Controls("TB_Q_" & i) < QD_Arome Then MsgBox "total " & QD_Arome & ",dosage " & fr.Controls("TB_Q_" & i): test = True
Else
MsgBox "entrer une valeur,svp": Creation_Liquide.Text_Q_Fiole.SetFocus


End If



'MsgBox "Tbox_Dosage.Name " & Mid(Tbox_Dosage.Name, 1)
'MsgBox "Tbox_Dosage.Value " & Tbox_Dosage.Value
End Sub
 

Discussions similaires