Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.
Icône de la ressource

VBA - Titres des champs directement en TextBox ou ComboBox (plus besoin de Labels) V4

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Dudu2

XLDnaute Barbatruc
Dudu2 a soumis une nouvelle ressource:

Suivre Ajouter un marque-page
Cette ressource repose sur une idée originale de @fanch55 adaptée par @patricktoulon et @Dudu2.

Le fichier à télécharger contient la Class_BuiltInFieldName qui permet de créer les titres des champs en TextBox et ComboBox. et de gérer leur affichage / masquage automatique lors de la saisie.
Cela permet de se passer des Labels pour désigner les titres des champs à saisir, car ces titres sont directement placés dans les champs.
En savoir plus sur cette ressource...
 
Dernière édition:
Bonjour @Dudu2
avant tout dit toi bien que ce sont des remarques constructives
perso je trouve que tu a un peu usiner par rapport à la conclusion que l'on a eu dans la discussion sur le forum


tu ajoute une fonction pour déterminer le parent alors que le seul soucis c'est le multipage
cela peut être fait dans le classing( et hop une fonction en moins )en l'occurrence ici dans la "SetControlTitle"

2° je vois dans l'event change .visible et .backstyle
tu m'explique ce besoins ?
VB:
Private Sub Control_Change(Control As MSForms.Control)
    Dim UserForm As Object
   
    Set UserForm = GetUserFormFromControl(Control)
    UserForm.Controls(PrefixTitle & Control.Name).Visible = (Len(Control.Value) = 0)
    Control.BackStyle = Abs(Not (Len(Control.Value) = 0))
End Sub

(pour info quand tu envois un object dans une fonction il arrive avec toutes ses propertie et membre)
me semble t il
la technique adoptée, si je me souviens bien ; c'est la superposition d'un textbox jumeau(en dessous) et l'original transparent ou pas
et pour moi ça s'arrête là

3° je vais faire l'impasse sur le tableau de classe qui est redimé en haute de sub et instruit en bas

alors que je te l'ai dit me semble t il utilise une collection même dans la classe

apprends a simplifier et rendre limpide tes codes

exemple :
dans mon userform

VB:
'*****************************************************************************************************
'    ___     _     _______  __      _   ____  _   _  _______  ___     _   _   _    ___     _     _.
'   //  \\  /\\      //    // \\   //  //    //  //    //    //  \\  //  //  //   //  \\  //|   //
'  //___// //__\    //    //__//  //  //    //__//    //    //   // //  //  //   //   // // |  //
' //      //   \\  //    //  \\  //  //    //  \\    //    //   // //  //  //   //   // //  | //
'//      //    // //    //   // //  //___ //    \\  //     \\__// //__//  //___ \\__// //   |//
'****************************************************************************************************
'                              collection module classe patricktoulon
'                                         mask titre pour textbox
'a partir d'une idée de @fanch55 avec les label
'ici nous allons utiliser simplement des textbox superposés
'en ajoutant des textbox dynamiquement et le placant en dessous  le textbox original
'le textbox original devient transparent si il est vide
'version 1.0
'Date version 24/02/2025
Option Explicit
Dim cls As New TextboxTitle

Private Sub UserForm_Activate()
    cls.SetMasktTitle TextBox11, "Nom:"
    cls.SetMasktTitle TextBox12, "Prénom:", vbBlue, vbYellow
    cls.SetMasktTitle TextBox13, "sexe:"
    cls.SetMasktTitle TextBox14, "Age:"
    cls.SetMasktTitle TextBox15, "Téléphone:"
    cls.SetMasktTitle TextBox16, "Adresse:"
    cls.SetMasktTitle TextBox17, "Complement adresse:"
    cls.SetMasktTitle TextBox18, "Code postal:"
    cls.SetMasktTitle TextBox19, "Ville:"
    cls.SetMasktTitle TextBox20, "email:"
End Sub
et rien d'autre
dans mon module classe nommé "TextboxTitle"
VB:
'*****************************************************************************************************
'    ___     _     _______  __      _   ____  _   _  _______  ___     _   _   _    ___     _     _.
'   //  \\  /\\      //    // \\   //  //    //  //    //    //  \\  //  //  //   //  \\  //|   //
'  //___// //__\    //    //__//  //  //    //__//    //    //   // //  //  //   //   // // |  //
' //      //   \\  //    //  \\  //  //    //  \\    //    //   // //  //  //   //   // //  | //
'//      //    // //    //   // //  //___ //    \\  //     \\__// //__//  //___ \\__// //   |//
'****************************************************************************************************
'                              collection module classe patricktoulon
'                                         mask titre pour textbox
'a partir d'une idée de @fanch55 avec les label
'ici nous allons utiliser simplement des textbox superposés
'en ajoutant des textbox dynamiquement et le placant en dessous  le textbox original
'le textbox original devient transparent si il est vide
'version 1.0
'Date version 24/02/2025
Option Explicit

Public WithEvents TextBox As MSForms.TextBox ' event textbox
'
Dim collect As Collection  'object collection contenant les instances de classe

Public index' a supprimer apres verif

Dim i& 'a supprimer apres verif
Public Function SetMasktTitle(Ref As Object, Xtitle As String, Optional F_Color& = vbBlack, Optional B_Color& = vbWhite)
    Dim txtF As MSForms.TextBox, NewClass As TextboxTitle, ParentX As Object
    Me.index = 0
    If collect Is Nothing Then Set collect = New Collection
    If TypeName(Ref.Parent) = "Page" Then Set ParentX = Ref.Parent.Parent Else Set ParentX = Ref.Parent
    Set txtF = ParentX.Controls.Add("Forms.TextBox.1", "XXX" & i, True)
    With txtF
        .ForeColor = &H80000010
        .BackColor = Ref.BackColor
        Set .Font = Ref.Font
        .BorderStyle = Ref.BorderStyle
        .BorderColor = Ref.BorderColor
        .Value = Xtitle
        .Move Ref.Left, Ref.Top, Ref.Width, Ref.Height
        txtF.ZOrder 1
        With Ref: .BackStyle = 0: .BackColor = B_Color: .ForeColor = F_Color: End With
    End With
    Set NewClass = New TextboxTitle
    Set NewClass.TextBox = Ref
    i = i + 1: NewClass.index = i'a supprimer apres verif
    collect.Add NewClass
End Function

Private Sub Class_Terminate()
Set collect = Nothing
End Sub

Private Sub TextBox_Change()
    MsgBox index' a supprimer apres verif
    TextBox.BackStyle = Abs((Len(TextBox.Value) > 0))
End Sub
comme tu peux le voir dans le code j'ai mis une variable index et une variable i ( qui ne sert que pour la démo ;elle peuvent être supprimée dans le code )
a l'utilisation on voit bien que le msgbox dans le change ne se répète pas quand on change le textbox
c'est simple et limpide
je joins le fichier exemple

Amicalement : patrick😉
 

Pièces jointes

les explications sont pas tout à fait exact mais c'est pas loin
il y a aussi la portée des variables aussi qui exigerons le "Me.membre" dans le code selon l'utilisation et donc un repeat event
dans mon exemple la classe mère (cls)contient toutes les autres par la collection et je n'ai pas d'effet repeat event
😉
et c'est quand même plus propre avec une collection
a moins que l'on ai des choses(membre ou propertie) à modifier dynamico dans les instances c'est mieux d'utiliser une collection

du coup j'ai ajouté la combo dans le mien ,çà m'ennuie je suis obligé de changer son nom 🤣🤣je peux plus l'appeler "textboxtitle" si il y a les combo avec . je vais lui redonner son nom initial "filigraneControl"
 
les explications sont pas tout à fait exact mais c'est pas loin
C'est toi qui le dis... Pour moi elles sont 100% exactes.

Cependant il reste un problème que je viens de découvrir dans cette classe. Je travaille à le résoudre.
 
bon j'ai télécharger la v2
tu a nettoyé à moitié regarde ça fonctionne aussi bien
VB:
Option Explicit

Public WithEvents TextBox As MSForms.TextBox
Public WithEvents ComboBox As MSForms.ComboBox
Private ClassCollection As Collection
'

'---------------------------------------
'Set a TextBox or ComboBox Control Title
'---------------------------------------
Public Sub SetControlTitle(Control As MSForms.Control, Titre As String, Optional ForeColor As Long = &H80000010)
    Dim BuiltInFieldName As Class_BuiltInFieldName, parent As Object
    
     If TypeName(Control.parent) = "Page" Then Set parent = Control.parent.parent Else Set parent = Control.parent
      
    'Create the Class Collection on 1st call from caller Class instance
    If ClassCollection Is Nothing Then
        Set ClassCollection = New Collection
    End If
    
    'Dynamic TextBox for the title of the Control
    With parent.Controls.Add("Forms.Textbox.1", PrefixTitle & Control.Name, True)
        .ForeColor = ForeColor
        .BackColor = Control.BackColor
        .Font.Name = Control.Font.Name
        .Font.Size = Control.Font.Size
        'If Control.Font.Bold Then .Font.Bold = True
        'If Control.Font.Italic Then .Font.Italic = True
        .SpecialEffect = Control.SpecialEffect
        .BorderStyle = Control.BorderStyle
        .BorderColor = Control.BorderColor
        .Value = Titre
        .Move Control.Left, Control.Top, Control.Width, Control.Height
    End With

    'The Control
    With Control
        'Must be initialized with transparent BackStyle
        .BackStyle = fmBackStyleTransparent
        
        'Must be set foreground
        Control.ZOrder 0
        
        'Must have its Class instance
        Set BuiltInFieldName = New Class_BuiltInFieldName
        
        'Set variables of the Control Class instance
        With BuiltInFieldName
            
            Select Case TypeName(Control)
                Case "TextBox"
                    Set .TextBox = Control
                Case "ComboBox"
                    Set .ComboBox = Control
            End Select
        End With
        
        'Add the Control instance to the Class Collection
        ClassCollection.Add BuiltInFieldName
    End With
End Sub

Private Sub TextBox_Change()
    Call Control_Change(TextBox)
End Sub

Private Sub ComboBox_Change()
    Call Control_Change(ComboBox)
End Sub

'-------------------------------------------------
'Title management of a TextBox or ComboBox Control
'-------------------------------------------------
Private Sub Control_Change(Control As MSForms.Control)
     Control.BackStyle = Abs(Not (Len(Control.Value) = 0))
End Sub
j'ai utilisé une variable parent comme tu l'avais fait mais je n'aime pas trop utiliser des constantes vba
dans le mien c'est parentX
 
La fonction GetUserFormFromControl() est une fonction générique que j'utilise quand j'ai besoin de savoir le UserForm d'un Control où qu'il soit dans le UserForm (direct, en Frame, en Multipage ou le tout imbriqué les uns dans les autres).
C'est clair et net, pas besoin de se poser de question sur ce que ça fait.

Avec ton instruction:
VB:
If TypeName(Control.parent) = "Page" Then Set parent = Control.parent.parent Else Set parent = Control.parent
D'abord ça parait mystérieux pour qui n'est pas parfaitement au fait de ces parentés, et en plus si je mets la TextBox directement dans un Multipage ça plante.

Tu as éliminé la variable Public UserForm As Object.
Soit ! Mais je préfère la garder pour rendre invisible la TextBox du titre. Vraiment ça ne "mange pas de pain" !

V3 publiée pour corriger le bug du Control.Parent.
 
D'ailleurs tu n'as nullement besoin de chercher le Parent du Control.
Ta version du code corrigée.
VB:
Option Explicit

Public WithEvents TextBox As MSForms.TextBox
Public WithEvents ComboBox As MSForms.ComboBox
Private ClassCollection As Collection
'

'---------------------------------------
'Set a TextBox or ComboBox Control Title
'---------------------------------------
Public Sub SetControlTitle(Control As MSForms.Control, Titre As String, Optional ForeColor As Long = &H80000010)
    Dim BuiltInFieldName As Class_BuiltInFieldName
   
    'Create the Class Collection on 1st call from caller Class instance
    If ClassCollection Is Nothing Then
        Set ClassCollection = New Collection
    End If
 
    'Dynamic TextBox for the title of the Control
    With Control.parent.Controls.Add("Forms.Textbox.1", "Titre_" & Control.Name, True)
        .ForeColor = ForeColor
        .BackColor = Control.BackColor
        .Font.Name = Control.Font.Name
        .Font.Size = Control.Font.Size
        'If Control.Font.Bold Then .Font.Bold = True
        'If Control.Font.Italic Then .Font.Italic = True
        .SpecialEffect = Control.SpecialEffect
        .BorderStyle = Control.BorderStyle
        .BorderColor = Control.BorderColor
        .Value = Titre
        .Move Control.Left, Control.Top, Control.Width, Control.Height
    End With

    'The Control
    With Control
        'Must be initialized with transparent BackStyle
        .BackStyle = fmBackStyleTransparent
     
        'Must be set foreground
        Control.ZOrder 0
     
        'Must have its Class instance
        Set BuiltInFieldName = New Class_BuiltInFieldName
     
        'Set variables of the Control Class instance
        With BuiltInFieldName
         
            Select Case TypeName(Control)
                Case "TextBox"
                    Set .TextBox = Control
                Case "ComboBox"
                    Set .ComboBox = Control
            End Select
        End With
     
        'Add the Control instance to the Class Collection
        ClassCollection.Add BuiltInFieldName
    End With
End Sub

Private Sub TextBox_Change()
    Call Control_Change(TextBox)
End Sub

Private Sub ComboBox_Change()
    Call Control_Change(ComboBox)
End Sub

'-------------------------------------------------
'Title management of a TextBox or ComboBox Control
'-------------------------------------------------
Private Sub Control_Change(Control As MSForms.Control)
     Control.BackStyle = Abs(Not (Len(Control.Value) = 0))
End Sub
 
Salut Dudu,
Comme l'avait fait remarqué @patricktoulon ,
on peut assigner toutes les propriétés du Font avec un set :
Enrichi (BBcode):
    With Control.Parent.Controls.Add("Forms.Textbox.1", PrefixTitle & Control.Name, True)
        .ForeColor = ForeColor
        .BackColor = Control.BackColor
         Set .Font = Control.Font
'        .Font.Name = Control.Font.Name
'        .Font.Size = Control.Font.Size
        'If Control.Font.Bold Then .Font.Bold = True
        'If Control.Font.Italic Then .Font.Italic = True
 
Bonjour les détecteurs de champs,

@fanch55, certes on peut faire ça, mais on fait venir toutes les propriétés de la Font du Control dans le Titre qui ne sont pas dans le code actuel "on purpose":
- Color (alors que la couleur de la Font du titre est un paramètre ajustable optionnel)
- Bold (non propagé dans le code car en commentaire)
- Italic (non propagé dans le code car en commentaire)
Après si tu préfères tout propagé, tu adaptes.
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

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