SetFocus avec un ComboBox

Xtian_Québec

XLDnaute Occasionnel
Salut le forum,
J'ai un problem avec la function SetFocus. Avec un UserForm qui contient 3 Combobox (cmb1, cmb2 et cmb3) ainsi que plusieurs TextBox (txb1,txb2,...).

Je veux que mon cmb2 soit sélectionner lorsqu'une valeur est sélectionné dans cmb1.
Pour dirirger le curseur dans cmb2, j'utilise la routine cmb1_Change et cmb2.SetFocus dans ma routine. Lorsqu'un item est sélectionné dans mon cmb1, le focus se retrouve dans cmb2 et tout fonctionne correctement.

Mes utilisateurs aimerait entrer les premières lettres des items de la liste cmb1 au lieu d'ouvrir la liste et sélectionner l'item dans la liste.
Avec cmb_Change, dès qu'une letter est inscrite dans cmb1, le code s'exécute (cmb_Change...)
Si plus d'un item commence avec la meme letter (Fraise-Framboise-Fruits), dès que la letter F est inscrite dans cmb1, l'item "Fraise" est sélectionné et le curseur se déplace dans cmb2 (cmb_Change + cmb2.SetFocus).

Pour permettre à l'utilisateur d'écrire plus d'une letter dans cmb1, j'ai change ma routine cmb1_Change pour cmb1_AfterUpdate. Comme le code sera execute seulement lorsque l'utilisateur utilisera la touché "TAB" ou la touché "ENTER", l'utilisateur peut écrire plus d'une letter.
Si l'utilisateur écrit "F" dans le cmb1, l'item "Fraise" est affiché...si on ajoute d'autres lettres dans cmb1 "F+R+A+M", l'item "Framboise sera affiché dans le cmb1. Si TAB ou ENTER, "Framboise" est sélectionné mais le SetFocus ne se dirige pas dans cmb2...Le curseur se retrouve dans txb1...

Si j'utilise cmb1_Change, le SetFocus = cmb2 et c'est ce que je veux
Si j'utilise cmb1_AfterUpdate, le SetFocus ne fonctionne plus et le curseur se retrouve dans txb1...

la propriété "Style" est "0-fmStyleDropDownCombo" J'ai essayé avec 2-fmStyleDropDownList" et j'ai le meme problem. J'ai fait des recherches pour les autres proprieties de mes cmb et je ne trouve aucune solution...

J'a également effectué d'autres recherches sur le web et je ne trouve aucune solution.
Quelqu'un peut m'expliquer pourquoi le SetFocus ne fonctionne pas avec le AfterUpdate?

Merci pour votre aide
Xtian
 

Xtian_Québec

XLDnaute Occasionnel
Bonjour Nicole,
Ton code est très bien mais en inscrivant les lettres dans le combobox, je comprend que la selection est dirigée vers les items qui contiennent les lettres inscrites. La liste est interactive selon les lettres inscrites dans le champ. Les utilisateurs de mon application aimerait utiliser la touche TAB ou ENTER lorsque l'item desiré est affiché dans le champ. Ton code manipule la liste mais ne renvoit pas la prochaine valeur possible.

Pour ce faire, il faudrait que le code "affiche" l'item correspondant dans le champ au fur et à mesure que les lettres sont sélectionnées dans le champ.
Si l'utilisateur inscrit "Le p",ta liste affiche 2 items (LE PACIFIQUE et LE PARIS). Pour répondre au besoin de mes utilisateurs, le champ devrait afficher "LE PACIFIQUE" car c'est le premier item disponible dans la liste. Si l'utilisateur continue d'entrer des lettres comme "Le par", l'item "LE PARIS" devrait s'afficher dans le champ car c'est le seul item possible.
En appuyant sur TAB ou ENTER, l'item serait sélectionné et le SetFocus se déplacerait vers le champ suivant.

Présentement, si j'écris "Le par" et que j'utilise TAB ou ENTER, la valeur "Le Par" est saisie comme valeur...
Je peux tenter de modifier ce code mais comme tu l'as développé, je penses qu'un petit ajustement pour afficher la valeur désirée serait possible.

Je vais tenter d'ajuster ton code mais si tu as une solution pour simplement sélectionner la prochaine valeur disponible dans la liste, je vais l'utiliser.

Merci beaucoup de m'aider.
Xtian
 

job75

XLDnaute Barbatruc
Bonjour Xtian, Nicole,

Si la question concerne bien cmb2.SetFocus cette instruction est inutile quand on quitte cmb1 par les touches Tab ou Enter.

Donnez aux propriétés TabIndex des contrôles les bonnes valeurs :

- cmb1 => 0

- cmb2 => 1

- txb1 => 2

A+
 

Xtian_Québec

XLDnaute Occasionnel
Merci Job75,
Les TabIndex sont bien identifies dans mon code mais selon la selection effectuée dans cmb1 (index 1), il est possible que le cmb2 (index 2) ne soit plus visible (j'affiche seulement les cmb que l'utilisateur peut faire des choix selon sa selection dans cmb1 (index 1)). Dans le cas où seulement le cmb3 (index 3) doit s'afficher dans le userform après la selection de l'item dans cmb1 (index 1), la touché TAB dirigera le curseur dans cmb2 (index 2) qui n'est pas visible...
Je veux que le curseur soit dirigé dans le cmb3 (index 3). Voilà pourquoi je ne peux pas utiliser la navigation au contrôle suivant avec TAB...Je dois identifier la valeur dans le cmb1 et utiliser le SetFocus pour diriger le curseur au bon endroit.

Nicole,
j'ai validé le MatchEntry=MatchFirstLetter dans ton fichier initial...
Malheureusement, cette propriété ne permet pas la saisie de plusieurs lettres dans le champ...
Comment peut-on écrire plus d'une lettre dans le champ et afficher l'item identifié dans la liste (le premier si plus d'un item correspond à la ou les lettres inscritent dans le champ de saisie)
dans ton fichier, j'aimerais qu'après avoir ecrit les lettres "Le PAR", "LE PARIS" soit afficher dans le champ sans avoir à sélectionner cet item avec la souris... Si l'item est affiché, il sera sélectionné lorsque la touche TAB sera utilise par l'utilisateur
Merci encore pour ton aide.
Xtian
 

job75

XLDnaute Barbatruc
Re,
j'aimerais qu'après avoir ecrit les lettres "Le PAR", "LE PARIS" soit afficher dans le champ sans avoir à sélectionner cet item avec la souris...
Mettre la propriété MatchEntry de cmb1 sur 2 - fmMatchEntryNone et adapter la macro :
Code:
Private Sub cmb1_Change()
If Len(cmb1) = 6 Then cmb1.ListIndex = Application.Match(cmb1 & "*", cmb1.List, 0) - 1
'---
End Sub
A+
 

Xtian_Québec

XLDnaute Occasionnel
Merci Job75 et Nicole.
La suggestion de Job75 demandait que j'identifie quand l'item doit être sélectionné (selon le nombre de caractère saisie - 6 dans la suggestion) et comme certaine liste contiennent des items qui peuvent être identifié seulement après un nombre de caractère plus grand que 6, il m'aurait fallu adapter tous mes codes selon le nombre de caractères possibles dans chaque liste...Cette suggestion est très bien si tous les items peuvent être identifies avec un meme nombre de caractères...Pour ceux qui ont un nombre de caractères semblalbles dans leurs liste, cette method fonctionne très bien. Merci Job75.

J'ai opté pour la suggestion de Nicole en utilisant la propriété suggérée par Job75 (2 - fmMatchEntryNone) et ça fonctionne...
L'utilisateur inscrira autant de lettre qu'il le desire jusqu'à ce que l'item desiré soit en haut de liste.
Lorsque l'item est en haut de liste (une ou plusieurs lettres entrées), la touché TAB exécutera le code
ComboBox1_Exit et sélectionnera cet item et le set focus ira au prochain champ desire. Merci Nicole.

Il me reste maintenant à appliquer cette logique dans mon application.

Je suis content car ce soir, je vais me coucher plus intelligent qu'hier...

Merci encore Job75 et Nicole.
 

Xtian_Québec

XLDnaute Occasionnel
Nicole,
J'avais conservé ton post # 1 ouvert et je l'adaptais et faisais les modifs au fur et à mesure que je recevais tes nouvelle informations...Comme les nouveaux codes étaient en format text dans les réponses, je les ajoutais à tes codes precedents...

Désolé de ne pas avoir identifié le frmMatchEntryNone dans tes posts subséquents...
En conclusion, tu m'as permis de soultionner mon probleme et j'en suis très reconnaissant.
Merci mille fois!
Xtian
A+
 

job75

XLDnaute Barbatruc
Bonjour le forum,

Qu'arrive-t-il à Nicole ? 2 - fmMatchEntryNone n'est pourtant qu'une simple évidence.

Et en général 1 - MatchEntryComplete fait l'affaire.

A+
 

Pièces jointes

  • Classeur(1).xlsm
    24 KB · Affichages: 56
Dernière édition:

job75

XLDnaute Barbatruc
Re,
Cette méthode ne limite pas le nombre de caractère à inscrire dans le champ de saisie.
Si l'on veut qu'un seul caractère soit proposé pour une nouvelle frappe :
Code:
Private Sub cmb1_Change()
Static flag As Boolean
If flag Then Exit Sub
Dim x$, i As Variant
flag = True
x = cmb1
i = Application.Match(x & "*", cmb1.List, 0)
If IsNumeric(i) Then
  cmb1 = Left(cmb1.List(i - 1), Len(x) + 1)
  cmb1.SelStart = Len(x)
  cmb1.SelLength = 1
End If
flag = False
End Sub
Ici avec 2 - fmMatchEntryNone.

Fichier (2).

A+
 

Pièces jointes

  • Classeur(2).xlsm
    26 KB · Affichages: 29

job75

XLDnaute Barbatruc
Bonjour Xtian, le forum,

Pour pouvoir revenir facilement en arrière par effacement du caractère en surbrillance :
Code:
Private Sub cmb1_Change()
Static flag As Boolean, L& 'variables mémorisées
If flag Then Exit Sub
Dim x$, i As Variant
x = cmb1
i = Application.Match(x & "*", cmb1.List, 0)
If x <> "" And IsNumeric(i) Then
  If Len(x) < L Then x = Left(x, Len(x) + IsError(Application.Match(x, cmb1.List, 0))) 'si effacement
  flag = True
  cmb1 = Left(cmb1.List(i - 1), Len(x) + 1)
  flag = False
  cmb1.SelStart = Len(x)
  cmb1.SelLength = 1 'dernier caractère en surbrillance
End If
L = Len(cmb1)
End Sub
Fichier (3).

Bonne journée.
 

Pièces jointes

  • Classeur(3).xlsm
    28 KB · Affichages: 34
Dernière édition:

job75

XLDnaute Barbatruc
Re,

Autre solution, dans ce fichier (4) on utilise une TextBox :
Code:
Private Sub txb1_Change()
Static flag As Boolean, L& 'variables mémorisées
If flag Then Exit Sub
Dim P As Range, x$, i As Variant
Set P = Range("A1:A7") 'plage à adapter
x = txb1
i = Application.Match(x & "*", P, 0)
If x <> "" And IsNumeric(i) Then
  If Len(x) < L Then x = Left(x, Len(x) + IsError(Application.Match(x, P, 0))) 'si effacement
  flag = True
  txb1 = Left(P(i), Len(x) + 1)
  flag = False
  txb1.SelStart = Len(x)
  txb1.SelLength = 1 'dernier caractère en surbrillance
End If
L = Len(txb1)
End Sub
A+
 

Pièces jointes

  • Classeur(4).xlsm
    29.8 KB · Affichages: 38

Discussions similaires

Statistiques des forums

Discussions
312 087
Messages
2 085 198
Membres
102 815
dernier inscrit
Henridic