Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2013 Userform modifier "set focus" pour revenir sur dernière textbox utilisée

jptaz15

XLDnaute Nouveau
Bonjour à tous,

j'ai beau chercher, mais je ne trouve pas exactement ce que j'ai besoin. Dans mon userform, j'ai un cadre avec plusieurs textbox et à l'extérieur du cadre une listbox avec différents éléments qui, lorsque double cliqués vont s'insérer dans la textbox choisie. Cependant, à chaque fois que je clique sur un mot dans ma listbox et que je reviens dans mes textbox, le focus retourne sur la première textbox, ce qui est peut être énervant lorsqu'il y en a beaucoup.

Y a t-il un moyen de conserver le curseur sur la dernière textbox utilisée? J'ai pensé utilisé "set focus", mais je ne vois pas comment...

Voici en pièce jointe une exemple avec qq textbox, mais noter qu'il devrait y en avoir une trentaine...

merci pour votre aide
 

Pièces jointes

  • double clic.xlsm
    22.2 KB · Affichages: 16
Solution
bonjour
1° vire moi ce module classe
2° vire moi ce module qui sert pour la variable public
3° vire moi ce code dans le userform

4° pour libérer la listbox et reprendre le focus sur le textbox precedement sélectionné il te faut utiliser l'event adequat
voilà maintenant que c'est propre met ce code dans le userform
VB:
Option Explicit
Public WithEvents TbTX As MSForms.TextBox
Dim cls() As New UserForm1
Public activeTxTbox As Object

Private Sub ListBox1_Click()
activeTxTbox = ListBox1.Value 'pas besoins qu'il est le focus pour etre bien ciblé on lui met la valeur choisi
End Sub

'FACULTATIF!!!!!!!!!!
Private Sub ListBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
'With activeTxTbox...

cp4

XLDnaute Barbatruc
Bonjour,

Rien ne fonctionne comme tu nous l'expliques. Demande plutôt de l'aide à celui qui t'as proposé les modules de classe. Désolé, de ne pouvoir t'aider.

Bonne journée.
 

patricktoulon

XLDnaute Barbatruc
bonjour
1° vire moi ce module classe
2° vire moi ce module qui sert pour la variable public
3° vire moi ce code dans le userform

4° pour libérer la listbox et reprendre le focus sur le textbox precedement sélectionné il te faut utiliser l'event adequat
voilà maintenant que c'est propre met ce code dans le userform
VB:
Option Explicit
Public WithEvents TbTX As MSForms.TextBox
Dim cls() As New UserForm1
Public activeTxTbox As Object

Private Sub ListBox1_Click()
activeTxTbox = ListBox1.Value 'pas besoins qu'il est le focus pour etre bien ciblé on lui met la valeur choisi
End Sub

'FACULTATIF!!!!!!!!!!
Private Sub ListBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
'With activeTxTbox: .SetFocus: .SelStart = Len(.Value): End With 'si tu veux Vraiment qu'il est le focus

'Set activeTxTbox = Nothing' si tu veux le re rendre inconnu apres la mise de la valeur

End Sub

Private Sub TbTX_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Set UserForm1.activeTxTbox = TbTX
End Sub

Private Sub TbTX_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
End Sub

Private Sub UserForm_Activate()
Dim ctrl, a&
For Each ctrl In Me.Frame1.Controls
If TypeName(ctrl) = "TextBox" Then a = a + 1: ReDim Preserve cls(1 To a): Set cls(a).TbTX = ctrl
Next
End Sub

Private Sub UserForm_Initialize()
      ListBox1.List = Array("<Test1", "<Test2", "<Test3", "<Test4", "<Test5")
End Sub

voila c'est pas compliqué tout est dans le userform
 

Pièces jointes

  • select memo textbox.xlsm
    24.4 KB · Affichages: 8

jptaz15

XLDnaute Nouveau
Wow, merci beaucoup pour votre aide, c'est vraiment très apprécié! Si je peux me permettre, pour ma curiosité, si on voulait ajouter un item de la ListBox sans effacer les autres éléments entrés (texte entré manuellement ou autres éléments de la listbox) que faudrait-il modifier au code?

merci encore
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Moi ce que je ne comprends pas c'est pourquoi une trentaine de TextBox en dessous, et pas aussi une ListBox ?
On ne peut pas utiliser de SetFocus sur des contrôles spécifiques, c'est lié à la collection Controls de l'UserForm
 

Dudu2

XLDnaute Barbatruc
Bonsoir @patricktoulon,
Tu fais du code savant auquel je pige que dalle !

Quand tu écris Dim Cls() As New UserForm1 tu créés un UserForm1 dans le UserForm1 ?
Ça n'a pas de sens.

C'est quoi tous ces signes "<" dans l'Array ?
Array("<Test1", "<Test2", "<Test3", "<Test4", "<Test5")
Ça devrait pas être ?
Array("TextBox1", "TextBox2", "TextBox2", "TextBox3", "TextBox5")
 

jptaz15

XLDnaute Nouveau
Bonjour.
Moi ce que je ne comprends pas c'est pourquoi une trentaine de TextBox en dessous, et pas aussi une ListBox ?
On ne peut pas utiliser de SetFocus sur des contrôles spécifiques, c'est lié à la collection Controls de l'UserForm
Bonjour, je ne suis pas certain de comprendre la question désolé, je suis assez novice en VBA. Je pourrais sans doute améliorer mon userform pour que ce soit moins compliqué. J'y suis allé comme je pensais
 

patricktoulon

XLDnaute Barbatruc
re
Bonsoir @Dudu2
VB:
Quand tu écris Dim Cls() As New UserForm1 tu créés un UserForm1 dans le UserForm1 ?
Ça n'a pas de sens.
je ne sais combien de fois j'ai du le répéter je le fait encore ce soir

tout d'abords il faut bien comprendre qu'un MODULE Userform (et je dis bien "MODULE"et non FORM ) ) est un module avant tout!!!
et pour être précis un module classe
de même qu'un module classe ou le module thisworkbook
parti de la je fait exactement ce que je ferais dans un module classe pour des controls
a savoir je déclare dim cls() qui sera le tableau d'instance de classe userform1
que je redim preserve dans un boucle

il n'y a aucune différence avec un module "classe "
l'avantage c'est la transportabilité du module userform

je cite encore une fois mon calendrier (Responsif) qui en est un exemple concret et qui démontre que cette méthode est fiable et pérenne et qui comptabilise un peu plus de 1700 téléchargement sur 4 forums différents XLD ayant la dernier version
bien trop l'ignorent ou comprennent mal cette pratique c'est dommage
le transport de module a un intéret certain pour le trafert de module dans plusieurs fichiers

pour l'array les symbole sont ceux qui étaient écrits déjà à la base
et non ce n'est pas le nom des textbox qui doivent être listé

le projet de notre ami est seulement de sélectionner un textbox et de pouvoir mémoriser l'object textbox pour que la sélection de la liste atterrisse dedans
c'est juste une solution pour palier a la perte de focus du texbox quand on est dans la listbox

si je te le fait avec un module classe est ce que ca t'aiderait a mieux comprendre ???

c'est pas plus compliqué que cela
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Oui enfin je ne comprend pas la finalité quoi… Moi dès qu'il y a plusieurs TextBox qui servent à la même chose je songe à faire en sorte de n'en avoir qu'une et à ranger ce qui y est saisi dans des lignes différentes d'une ListBox. Comme ça il n'y aurait plus de problème de focus puisqu'une ligne sélectionnée d'une ListBox le demeure même si on change de contrôle.
 

patricktoulon

XLDnaute Barbatruc
@Dranreb nous ne savons qu'une infime partie de la finalité du projet
laissons notre amis nous en faire découvrir les aspects si il le désire
 

Dranreb

XLDnaute Barbatruc
Quand tu écris Dim Cls() As New UserForm1 tu créés un UserForm1 dans le UserForm1 ?
Ça n'a pas de sens.
Je suis entièrement d'accord, ça n'a pas de sens de réserver tout le jeu d'emplacements de mémoire de tout l'UserForm pour autant d'exemplaires d'un seul contrôle ne faisant pas partie de leurs collections Controls respectives, d'ailleurs inutiles, et n'est donc pas utilisé dans l'exemplaire affiché ! Il vaut certes mieux une classe support différente n'ayant que le minimum nécessaire comme c'était ébauché.
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Bonjour à tous,
Pour revenir au problème fonctionnel du début:
j'ai un cadre avec plusieurs textbox et à l'extérieur du cadre une listbox avec différents éléments qui, lorsque double cliqués vont s'insérer dans la textbox choisie.
Ne suffit-il pas de garder en mémoire la dernière TextBox sélectionnée ?
VB:
Private ActiveTextBox As Control

Private Sub UserForm_Initialize()
      ListBox1.List = Array("<Test1", "<Test2", "<Test3", "<Test4", "<Test5")
End Sub

Private Sub ListBox1_Click()
    If Not ActiveTextBox Is Nothing Then ActiveTextBox.Value = ListBox1.Value
End Sub

Private Sub TextBox1_Enter()
    Set ActiveTextBox = Me.TextBox1
End Sub
Private Sub TextBox2_Enter()
    Set ActiveTextBox = Me.TextBox2
End Sub
Private Sub TextBox3_Enter()
    Set ActiveTextBox = Me.TextBox3
End Sub
Private Sub TextBox4_Enter()
    Set ActiveTextBox = Me.TextBox4
End Sub
Private Sub TextBox5_Enter()
    Set ActiveTextBox = Me.TextBox5
End Sub
Je sais que c'est un peu trivial et que ce serait plus élégant de passer par une classe (ce que je ne sais pas faire sans investiguer) pour ne pas avoir à citer chaque TextBox, mais c'est d'une simplicité confondante. Tant qu'il n'y en a qu'un petit nombre.

Par contre je serais intéressé par un exemple (autre que celui fourni à ce stade par @patricktoulon) pour gérer les évènements des TextBox dans une classe dédiée. A moins de reprendre le code initialement fourni et fixer le problème.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Oui mais toutes mes tentatives de SetFocus sur une TextBox gérée à travers une classe support dédiée ont échoué jusqu'à présent. On ne peut prendre en charge ainsi que les évènement de la MSForms.TextBox, et pas ceux du MSForms.Control qui la supporte tel que Enter, Exit ni la méthode SetFocus. On ne peut pas déclarer un WithEvents Ctl As MSForms.Control et c'est bien dommage car ça m'aurait déjà été bien utile.
Mon module de classe CAssoTBx si vous voulez :
VB:
Option Explicit
Implements CAsso
Private Parent As ControlsAssociés, WithEvents TBx As MSForms.TextBox, Index As Long, Colonne As Long, Format As String, UsMode
Private Sub CAsso_Init(ByVal Lui As ControlsAssociés, ByVal Ctl As MSForms.IControl, ByVal Idx As Long, _
   ByVal Col As Long, ByVal Fmt As String, ByVal Mode As Variant)
   Set Parent = Lui: Set TBx = Ctl: Index = Idx: Colonne = Col: Format = Fmt: UsMode = Mode
   End Sub
Private Function CAsso_Ctl() As MSForms.IControl
   Set CAsso_Ctl = TBx
   End Function
Private Function CAsso_Index() As Long
   CAsso_Index = Index
   End Function
Private Function CAsso_Col() As Long
   CAsso_Col = Colonne
   End Function
Private Function CAsso_Format() As String
   CAsso_Format = Format
   End Function
Private Function CAsso_Mode() As Variant
   CAsso_Mode = UsMode
   End Function
Private Property Let CAsso_Valeur(ByVal RHS As Variant)
   If IsEmpty(RHS) Then TBx.Text = "": Exit Property
   TBx.Text = VBA.Format$(RHS, Format)
   End Property
Private Property Get CAsso_Valeur() As Variant
   If TBx.Text = "" Then
      CAsso_Valeur = Empty
   ElseIf IsDate(TBx.Text) And Not Format Like "*&*" Then
      CAsso_Valeur = CDate(TBx.Text)
   ElseIf IsNumeric(TBx.Text) And Not Format Like "*&*" Then
      If Format Like "*€" Then CAsso_Valeur = CCur(TBx.Text) Else CAsso_Valeur = CDbl(TBx.Text)
   Else
      CAsso_Valeur = Trim$(TBx.Text)
      End If
   End Property
Private Sub TBx_Change()
   Parent.CAM_Change Me
   End Sub
Private Sub TBx_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
   Parent.CAM_KeyDown Me, KeyCode, Shift
   End Sub
Private Sub TBx_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
   Parent.CAM_KeyPress Me, KeyAscii
   End Sub
Private Sub TBx_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
   Parent.CAM_KeyUp Me, KeyCode, Shift
   End Sub
 
Dernière édition:

Discussions similaires

Réponses
23
Affichages
1 K
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…