Microsoft 365 Calcul TEXTBOX dans Userform

eric72

XLDnaute Accro
Bonjour,
Je cherche à faire des calculs de Textbox dans un Userform en sachant qu'elles ne sont pas toujours toutes renseignées à chaque fois, malgré cela j'aimerais que le calcul se fasse quand même en tenant compte de celles renseignées, donc j'ai adapté ce code mais ça ne va pas.
Ou est la boulette?
Merci à tous
 

Pièces jointes

  • Gestion Fiche Produit test.xlsm
    204 KB · Affichages: 31

eric72

XLDnaute Accro
Pour tout te dire Patrick je n'y comprends pas grand chose, cela t'ennuierais-t-il de traduire cela dans mon tableau(juste sur 2 frame) pour que je me rende compte de la complexité, comme ça je pourrais le dupliquer pour comprendre?
Ca serait top parce que là j'ai l'impression d'apprendre une nouvelle langue, lol!!!
Eric
 

patricktoulon

XLDnaute Barbatruc
et voilà
tu a jusqu'a 20 textbox possible par frames ça t'irra ou tu en veux plus ;)😅😅
VB:
Option Explicit
Public WithEvents txtB As MSForms.TextBox
Dim mesclasses() As New la_classe_a_toto
Public les4
Public UsF As Object
Public mamanFram
Function init_le_bourin(uf)
    Dim a&, e&, txt, mestextB(1 To 20) As Object, ctr As Object, z&, Fram
    For Each Fram In uf.Controls
        e = 0
        If TypeName(Fram) = "Frame" Then
            For Each txt In Fram.Controls
                If txt.Tag = "x" Or txt.Tag = "y" Then
                    a = a + 1: ReDim Preserve mesclasses(1 To a)
                    With mesclasses(a)
                        Set .txtB = txt:
                        Set .UsF = uf
                        Set .mamanFram = Fram
                        If txt.Tag = "x" Then e = e + 1: Set mestextB(e) = txt Else If txt.Tag = "y" Then Set mestextB(4) = txt
                        .les4 = mestextB
                    End With
                End If
            Next
            For z = a To a - 3 Step -1: mesclasses(z).les4 = mestextB: Next
        End If
    Next
End Function

'<<voila moins de 15 lignes et tout mes textboxs sont classés>>

'les 4 textbox freres sont bien distingués dans l'event
Private Sub TxtB_Change()    'le change c'est le meme pour tous
    Dim valeurs() As Double, I&
    ReDim valeurs(1 To UBound(les4))
    For I = 1 To UBound(les4)
        If Not les4(I) Is Nothing Then If les4(I).Value <> "" Then valeurs(I) = CDbl(les4(I)) Else valeurs(I) = 0
    Next
    
    Select Case mamanFram.Name 'selon le nom de la frame parent

    Case "josette"
        'je fait un calcul ici
    Case "yollande"
        'je fait un autre calcul ici

    Case "roberta"
        'je fait encore un autre calcul ici

        'etc..etc...
        'et TOUT !!!!!!!!!!!!!!!!les calcus se font avec valeurs(1) ,valeurs(2),valeurs(3) valeurs(4)

    End Select
 'juste pour le visuel
    UsF.visuel = mamanFram.Name & vbCrLf & les4(1).Name & " :" & valeurs(1) & vbCrLf & les4(2).Name & " :" & valeurs(2) & vbCrLf & _
    les4(3).Name & " :" & valeurs(3) & vbCrLf & les4(4).Name & " :" & valeurs(4) & vbCrLf & _
    "                     resultat :" & (valeurs(1) + valeurs(2) + valeurs(3)) * valeurs(4)


End Sub

'et tant qu'a faire on gere le keypress aussi dans la classe et on vire tout les keypress de l'userform hop hop hop !!!
Private Sub TxtB_KeyPress(ByVal keyascii As MSForms.ReturnInteger)
'le vrai code ET  au complet !!!!!! de patricktoulon
    Dim ctrl As Object
    Set ctrl = UsF.ActiveControl: Do While TypeName(ctrl) <> "TextBox": Set ctrl = ctrl.ActiveControl: Loop
    With ctrl
        If keyascii = 46 Then keyascii = 44
        If Chr(keyascii) Like "[!0-9|,-]" Then keyascii = 0
        If (Len(.Value) = 0 Or .Value Like "*,*") And Chr(keyascii) = "," Then keyascii = 0
        If Chr(keyascii) = "-" And .Value <> "" Then keyascii = 0
    End With
End Sub

franchement j'ai regardé ton fichier et autant ce que je dis pour toi c'est du javanais et autant quand je regarde ton code j'ai envie de fuir 😅😅
deja tu a une combobox dans tes frames ou pas
celle qui l'ont devrait stocker la plage entiere et n'afficher que la colonne que tu veux et tes vlookup byebye!!!! on a tout sur place

explique moi en français ce que tu veux faire comme calcul dans ta frame
le nom de la frame le nom des 4 ou plus textbox
essaie d’être clair parce ce que le code ne reflété pas une clarté
dans ton prochain message essaie d’écrire l'operation avec les nom des textbox a la place des valeur

et pour finir ;excusez mon franc parler mais je dis les choses comme je le penses sans détour, ça n'a rien de méchant ou agressif de ma part c'est ce que je suis 😂
 

Robert

XLDnaute Barbatruc
Repose en paix
Bonjour le fil, bonjour le forum,

Tu as très bien compris le principe ! Patrick aura certainement une solution plus efficace... Toutefois. en pièce jointe la version 3 de ton fichier.
J'ai supprimé les Select Case (Name) dans les modules de classes. d'Une part parce qu'ils étaient inutiles puisque les tableaux TTB ne permettaient pas un autre contrôle que ceux concernés et d'autre part parce que maintenant tout fonctionne. J'ai modifié les code des cases d'option Changer Coeff...
 

Pièces jointes

  • Éric_ED_v03.xlsm
    277.2 KB · Affichages: 3

eric72

XLDnaute Accro
et voilà
tu a jusqu'a 20 textbox possible par frames ça t'irra ou tu en veux plus ;)😅😅
VB:
Option Explicit
Public WithEvents txtB As MSForms.TextBox
Dim mesclasses() As New la_classe_a_toto
Public les4
Public UsF As Object
Public mamanFram
Function init_le_bourin(uf)
    Dim a&, e&, txt, mestextB(1 To 20) As Object, ctr As Object, z&, Fram
    For Each Fram In uf.Controls
        e = 0
        If TypeName(Fram) = "Frame" Then
            For Each txt In Fram.Controls
                If txt.Tag = "x" Or txt.Tag = "y" Then
                    a = a + 1: ReDim Preserve mesclasses(1 To a)
                    With mesclasses(a)
                        Set .txtB = txt:
                        Set .UsF = uf
                        Set .mamanFram = Fram
                        If txt.Tag = "x" Then e = e + 1: Set mestextB(e) = txt Else If txt.Tag = "y" Then Set mestextB(4) = txt
                        .les4 = mestextB
                    End With
                End If
            Next
            For z = a To a - 3 Step -1: mesclasses(z).les4 = mestextB: Next
        End If
    Next
End Function

'<<voila moins de 15 lignes et tout mes textboxs sont classés>>

'les 4 textbox freres sont bien distingués dans l'event
Private Sub TxtB_Change()    'le change c'est le meme pour tous
    Dim valeurs() As Double, I&
    ReDim valeurs(1 To UBound(les4))
    For I = 1 To UBound(les4)
        If Not les4(I) Is Nothing Then If les4(I).Value <> "" Then valeurs(I) = CDbl(les4(I)) Else valeurs(I) = 0
    Next
    
    Select Case mamanFram.Name 'selon le nom de la frame parent

    Case "josette"
        'je fait un calcul ici
    Case "yollande"
        'je fait un autre calcul ici

    Case "roberta"
        'je fait encore un autre calcul ici

        'etc..etc...
        'et TOUT !!!!!!!!!!!!!!!!les calcus se font avec valeurs(1) ,valeurs(2),valeurs(3) valeurs(4)

    End Select
 'juste pour le visuel
    UsF.visuel = mamanFram.Name & vbCrLf & les4(1).Name & " :" & valeurs(1) & vbCrLf & les4(2).Name & " :" & valeurs(2) & vbCrLf & _
    les4(3).Name & " :" & valeurs(3) & vbCrLf & les4(4).Name & " :" & valeurs(4) & vbCrLf & _
    "                     resultat :" & (valeurs(1) + valeurs(2) + valeurs(3)) * valeurs(4)


End Sub

'et tant qu'a faire on gere le keypress aussi dans la classe et on vire tout les keypress de l'userform hop hop hop !!!
Private Sub TxtB_KeyPress(ByVal keyascii As MSForms.ReturnInteger)
'le vrai code ET  au complet !!!!!! de patricktoulon
    Dim ctrl As Object
    Set ctrl = UsF.ActiveControl: Do While TypeName(ctrl) <> "TextBox": Set ctrl = ctrl.ActiveControl: Loop
    With ctrl
        If keyascii = 46 Then keyascii = 44
        If Chr(keyascii) Like "[!0-9|,-]" Then keyascii = 0
        If (Len(.Value) = 0 Or .Value Like "*,*") And Chr(keyascii) = "," Then keyascii = 0
        If Chr(keyascii) = "-" And .Value <> "" Then keyascii = 0
    End With
End Sub

franchement j'ai regardé ton fichier et autant ce que je dis pour toi c'est du javanais et autant quand je regarde ton code j'ai envie de fuir 😅😅
deja tu a une combobox dans tes frames ou pas
celle qui l'ont devrait stocker la plage entiere et n'afficher que la colonne que tu veux et tes vlookup byebye!!!! on a tout sur place

explique moi en français ce que tu veux faire comme calcul dans ta frame
le nom de la frame le nom des 4 ou plus textbox
essaie d’être clair parce ce que le code ne reflété pas une clarté
dans ton prochain message essaie d’écrire l'operation avec les nom des textbox a la place des valeur

et pour finir ;excusez mon franc parler mais je dis les choses comme je le penses sans détour, ça n'a rien de méchant ou agressif de ma part c'est ce que je suis 😂

Alors dans la frame "PLANTE" le "PRIX REVIENT"= (Prix d'achat*coeff)+(prix achat*transport)
Pour le coeff il est défini soit en clickant sur "Non rempotée" ou "Rempotée" ou alors en sélectionnant "cocher pour changer coeff" pour le mettre manuellement
La cb"TRANSPORTEUR" définit le "Transport" par le vlookup!!!

Pour le frame "POT" la CB "DIAMETRE" définit le coeff et le prix par vlookup le coeff peut être modifié manuellement en sélectionnant "cocher pour changer coeff"
le "PRIX REVIENT"= (Prix franco*coeff)+(prix achat*transport)

Pour le frame "PLAQUE" la CB "REF PRODUIT" définit le coeff le Nb Pl/Plaque et le prix par vlookup le coeff peut être modifier modifié manuellement en sélectionnant "cocher pour changer coeff
le "PRIX REVIENT" = (Coeff*prix franco)/ Nb Pl/Plaque
Etc...
 

patricktoulon

XLDnaute Barbatruc
allez j'explique
un module classe est un module object qui peux nous permetre de faire des action répétitive voir similaire
j'ai une particularité personnellement c'est que je code les instantiation et le subclassing dans le module classe lui meme j'explique plus bas

alors la fonction init_le_bourin
commencez par digérer ça
VB:
Option Explicit
Public WithEvents txtB As MSForms.TextBox    ' je declare l'event textbox
Dim mesclasses() As New la_classe_a_toto    'de declare une variable tableau qui contiendra les instances de classe
'dans une classe on peut pas declaré <<public les4(1 to 20)>>c'est pas possible
'je declare donc une variable VARIANT!!!!!!!! qui contiendra l'array des object textbox(les 20 ou moins )
' elle sera transformée en tableau dans le init
Public les4
Public UsF As Object    'je declare un object usf pour le userform
Public mamanFram    'je déclare un object pour la fram
'les objects usf et mamanfram seront respectivement le userform et une frame differente dans chaque instances
Function init_le_bourin(uf)
    Dim a&, e&, txt, mestextB(1 To 20) As Object, ctr As Object, z&, Fram, x
    For Each Fram In uf.Controls    'on boucle dans les controls du userform
        e = 0    'on réinitialise a zero la variable compteur qui me sert a stocker les textbox en tant que freres dans l'array mestexB
        x = 0
        If TypeName(Fram) = "Frame" Then    'si le controls est une frame alors
            For Each txt In Fram.Controls    'on boucle sur tout les textbox de cette frame
                If txt.Tag = "x" Or txt.Tag = "y" Then    ' si il ont le tag x ou y alors
                    a = a + 1: ReDim Preserve mesclasses(1 To a)    'on redimensionne  le tableau mesclasses de 1 de plus
                    x = x + 1
                    With mesclasses(a)    'donc avec cette instance de classe
                        Set .txtB = txt:    'le TxtB sera le txt(le textbox trouvé dans la boucle)
                        Set .UsF = uf    'usf sera le userform(uf argument injecté dans l'appel dans le userform avec "Me")
                        Set .mamanFram = Fram    'la mamanfram bien sur c'est la frame de la boucle fram

                        'et c'est là que l'on  determine les textbox dans l'array mestextB selon le tag x ou x
                        If txt.Tag = "x" Then e = e + 1: Set mestextB(e) = txt Else If txt.Tag = "y" Then Set mestextB(4) = txt
                        '.les4 = mestextB 'les4 devient enfin  l'array d'object textbox
                    End With
                End If
            Next
            'donc apartir de la on a classer les textbox en tant que txtB (event géré)
            'mais les classe n'ont pas tout les textbox de l'arraymestextB
            ' il faut donc les incrire dans les instance de classe
            'on remonte donc a la premiere instance de classe de textbox dans cette frame
            'et on incrit l'array dans les4
            For z = a To a - (x - 1) Step -1: mesclasses(z).les4 = mestextB: Next
        End If
    Next
End Function
 

patricktoulon

XLDnaute Barbatruc
et ben c'est simple
ça rien a foutre
'ca rien a foutre :pour le frame "POT" la CB "DIAMETRE" définit le coeff et le prix par vlookup le coeff peut être 'ca non plus modifié manuellement en sélectionnant "cocher pour changer coeff"
'le "PRIX REVIENT"=
dans ma classe dans l'event et dans le select case

VB:
select case mamanfram.name

'je suppose que prix c'est le textbox ou va le résultat !!!!!!!!!!!!!!!!!!!
'prix achat ne peut pas etre un nom de textbox il y a un espace !!!!!!!!!!!!!!!!!!!!!!!!!!
'heureusement que je t'ai demandé l’opération avec les nom de textbox a la place des valeurs
case"POT":with mamanfram: .prix= (.franco*.coeff)+(.prix_achat*.transport):end with

'tu fait pareil pour plante
'case"PLANTE":with mamanfram: ....avec les nom de text textboxs....................:end with

'case"blablabla"
etc...etc...
end select
 

patricktoulon

XLDnaute Barbatruc
on pourrait même encore simplifier dans le init car avec le select case mamanfram finalement c'est les parent frame qui commandent et que l'on met les opérations en dur avec les noms réel des textboxs
je suis sur le projet d'alain là je reviens toute a l'heure
 

eric72

XLDnaute Accro
Oups désolé, rectif:
Alors dans la frame "PLANTE" le "PRIX REVIENT"= (Prixachatplante*coeffplante)+(prixachatplante*transplante)
Pour le coeff il est défini soit en clickant sur "obnonrempotee" ou "obRempotee" ou alors en sélectionnant "cocher pour changer coeff" pour le mettre manuellement
La cb"CbTransporteur" définit le "Transport" par le vlookup!!!

Pour le frame "POT" la CB "diampot" définit le coeff et le prix par vlookup le coeff peut être modifié manuellement en sélectionnant "cocher pour changer coeff"
le "prpot"= (Prixpot*coeffpot)

Pour le frame "PLAQUE" la CB "refplaque" définit le coeff le Nb Pl/Plaque et le prix par vlookup le coeff peut être modifier modifié manuellement en sélectionnant "cocher pour changer coeff
le "prplaque" = (Coeffplaque*prixplaque)/ NbPlantePlaque
Etc...
 

patricktoulon

XLDnaute Barbatruc
donne moi au moins l’opération de la frame "FrCdt" c'est la seul qui a les textboxs dedans au complet je crois
faut être un peu moins brouillon je me casse la te a essayer de deviner
ou donne moi un userform qui est au complet avec tout les controls dans leur frame respectives ou tu du moins celui le plus a jour depuis le debut de cette discussion là j'ai le premier du post 1
et la formule avec les NOM!!!!!!!!! des controls
je te fait ça en 5 minutes après
 

Discussions similaires

Réponses
10
Affichages
356

Statistiques des forums

Discussions
312 182
Messages
2 086 004
Membres
103 086
dernier inscrit
jcreant