API - "SendMessage" - dans Excel
Résolu
lami20j
Messages postés
21331
Date d'inscription
Statut
Modérateur, Contributeur sécurité
Dernière intervention
-
lami20j Messages postés 21331 Date d'inscription Statut Modérateur, Contributeur sécurité Dernière intervention -
lami20j Messages postés 21331 Date d'inscription Statut Modérateur, Contributeur sécurité Dernière intervention -
Bonsoir,
J'ai une UserForm qui contient un TextBox et un ListBox.
A l'initialisation de UserForm, ListBox contient une plage des cellules.
Ce que je veut obtenir c'est que à chaque saisie dans la zone de texte la ListBox est exploré progressivement jusqu'à quand j'obtiens la correspondance exacte.
Merci d'avance pour votre aide,
lami20j
P.S. Voilà le code que je teste
Dans un module
Dans UserForm
J'ai une UserForm qui contient un TextBox et un ListBox.
A l'initialisation de UserForm, ListBox contient une plage des cellules.
Ce que je veut obtenir c'est que à chaque saisie dans la zone de texte la ListBox est exploré progressivement jusqu'à quand j'obtiens la correspondance exacte.
Merci d'avance pour votre aide,
lami20j
P.S. Voilà le code que je teste
Dans un module
Option Explicit Public Declare Function FindWindowEx Lib "user32" _ Alias "FindWindowExA" _ (ByVal hWnd1 As Long, _ ByVal hWnd2 As Long, _ ByVal lpsz1 As String, _ ByVal lpsz2 As String) As Long Public Declare Function SendMessage Lib "user32" _ Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, lParam As String) As Long Public Const LB_SELECTSTRING = &H18C
Dans UserForm
Option Explicit Dim hwndlst as Long Dim lngNbLigne As Long Private Sub UserForm_Initialize() lstnom.SetFocus lngNbLigne = Sheets("a").Range("b1").End(xlDown).Row For i = 2 To lngNbLigne If (Sheets("a").Cells(i, 7) <> "") Then lstnom.AddItem Sheets("a").Cells(i, 20) End If Next lstnom.ZOrder 0 hwndlst = FindWindowEx(0, 0, "lstnom", vbNullString) End Sub Private Sub txtnomsearch_Change() Dim nbenter As Long Dim txtarechercher As String txtarechercher = txtnomsearch.Text nbenter = SendMessage(hwndlst, _ LB_SELECTSTRING, 0, txtarechercher) End Sub
A voir également:
- API - "SendMessage" - dans Excel
- Liste déroulante excel - Guide
- Word et excel gratuit - Guide
- Déplacer colonne excel - Guide
- Si ou excel - Guide
- Excel moyenne - Guide
5 réponses
Bonjour lami,
les APIs, je connais très peu, je comprends le code, et en même
temps je ne sais si ma méthode est "meilleur" ?
J'ai tendance à toujours découper l'objet / diviser pour regner
Si je comprends bien tu veux un filtre automatique sur chaque
lettre ajouter dans la texte box.
à mon dernier cours de VB, on m'avait dit que le tri alphabétique
n'était pas inné chez les objets VBA, en lisant ton code cela me
rappelle qu'il existe quand même...
ceci dit le listbox contient un nombre d'item "visible" fixe, il
faut d'abord le fixer d'aprés la police choisi et la hauteur du
contrôle. Ce nombre devient le pas du controle lui-meme.
ensuite un simple routine de recherche dans les items d'après
les lettres saisies dans le textbox.
pour ton code, alors quelques modifications !
un textbox caché !
txt_hwndlst.Value
et la je ne suis pas sur, je crois que :
mais je ne réussit pas à le faire fonctionner, je ne connais pas
assez les APIs windows.
Lupin
les APIs, je connais très peu, je comprends le code, et en même
temps je ne sais si ma méthode est "meilleur" ?
J'ai tendance à toujours découper l'objet / diviser pour regner
Si je comprends bien tu veux un filtre automatique sur chaque
lettre ajouter dans la texte box.
à mon dernier cours de VB, on m'avait dit que le tri alphabétique
n'était pas inné chez les objets VBA, en lisant ton code cela me
rappelle qu'il existe quand même...
ceci dit le listbox contient un nombre d'item "visible" fixe, il
faut d'abord le fixer d'aprés la police choisi et la hauteur du
contrôle. Ce nombre devient le pas du controle lui-meme.
ensuite un simple routine de recherche dans les items d'après
les lettres saisies dans le textbox.
pour ton code, alors quelques modifications !
un textbox caché !
txt_hwndlst.Value
Option Explicit ' Private Sub cmd_Quitter_Click() Unload Me End Sub ' Private Sub UserForm_Initialize() Dim Boucle, Decalage As Long Dim lngNbLigne As Long lstnom.SetFocus lngNbLigne = Sheets("a").Range("B4:B65535").End(xlDown).Row Decalage = 4 'B4 For Boucle = 1 To (lngNbLigne - Decalage) If (Sheets("a").Cells((Boucle + Decalage), 2).Value <> "") Then lstnom.AddItem Sheets("a").Cells((Boucle + Decalage), 2).Value End If Next lstnom.ZOrder 0 txt_hwndlst.Value = FindWindowEx(0, 0, "lstnom", vbNullString) End Sub ' Private Sub txtnomsearch_Change() Dim nbenter As Long Dim txtarechercher As String txtarechercher = txtnomsearch.Text nbenter = SendMessage(txt_hwndlst.Value, LB_SELECTSTRING, 0, txtarechercher) End Sub
et la je ne suis pas sur, je crois que :
Private Sub txtnomsearch_Change() Call SendMessage(txt_hwndlst.Value, LB_SELECTSTRING, 0, txtnomsearch.Text) End Sub
mais je ne réussit pas à le faire fonctionner, je ne connais pas
assez les APIs windows.
Lupin
re:
VB versus API, en effet je n'ai utilisé les API qu'avec VB et
selon des recettes sans trop comprendre.
Avec VBS, on peut instancier pratiquement tout les objets
"windos", alors je crois que oui, VBS est supporté par VBA
qui lui est supporté par VB. Si je ne m'abuse pas c'est le
typage qui est vital !
exemple :
La routine :
devrait s'en doute s'écrire du genre :
afin de garantir le type transmit. Un contrôle de type assureras
un appli plus solide.
bonne continuité
Lupin
VB versus API, en effet je n'ai utilisé les API qu'avec VB et
selon des recettes sans trop comprendre.
Avec VBS, on peut instancier pratiquement tout les objets
"windos", alors je crois que oui, VBS est supporté par VBA
qui lui est supporté par VB. Si je ne m'abuse pas c'est le
typage qui est vital !
exemple :
La routine :
Private Sub txtnomsearch_Change() Call SendMessage(txt_hwndlst.Value, LB_SELECTSTRING, 0, txtnomsearch.Text) End Sub
devrait s'en doute s'écrire du genre :
Private Sub txtnomsearch_Change() Call SendMessage(CLng(txt_hwndlst.Value), _ LB_SELECTSTRING, 0, _ CStr(txt_hwndlst.Value)) End Sub
afin de garantir le type transmit. Un contrôle de type assureras
un appli plus solide.
bonne continuité
Lupin
re:
désolé je ne puis éditer le message (mon compte est bousillé).
CStr(txtnomsearch.Text)
Lupin
désolé je ne puis éditer le message (mon compte est bousillé).
CStr(txtnomsearch.Text)
Lupin
Re,
j'ai testé ce que tu m'as donné mais ça ne fonctionne pas.
Pourtant dans le livre de John Walkenbach
http://www.amazon.fr/exec/obidos/ASIN/0764547992/402-1288982-7386523
je vois des exemples avec les API Win
Pour l'instant pour me deplacer j'utilise la propriète
lstnom.MatchEntry = fmMatchEntryComplete
mais ça ne me satisfait pas.
Je vais essayer ce que tu m'as donné dans ton dernier poste.
Merci,
lami20j
j'ai testé ce que tu m'as donné mais ça ne fonctionne pas.
Pourtant dans le livre de John Walkenbach
http://www.amazon.fr/exec/obidos/ASIN/0764547992/402-1288982-7386523
je vois des exemples avec les API Win
Pour l'instant pour me deplacer j'utilise la propriète
lstnom.MatchEntry = fmMatchEntryComplete
mais ça ne me satisfait pas.
Je vais essayer ce que tu m'as donné dans ton dernier poste.
Merci,
lami20j
Hello lami20j,
Quelques jours ailleurs... je viens de voir ton invite à faire un tour ici.
J'utilise peu les API pour mes besoins courants.
Juste une question : tu fais saisir quelque chose dans une TextBox, et tu fais contrôler la saisie à partir de la liste de la ListBox, c'est ça ?
Ça revient à utiliser un Combo, ou je me trompe ?
C'est le besoin que je ne vois pas vraiment.
Quelques jours ailleurs... je viens de voir ton invite à faire un tour ici.
J'utilise peu les API pour mes besoins courants.
Juste une question : tu fais saisir quelque chose dans une TextBox, et tu fais contrôler la saisie à partir de la liste de la ListBox, c'est ça ?
Ça revient à utiliser un Combo, ou je me trompe ?
C'est le besoin que je ne vois pas vraiment.
Salut Armojax,
comment tu vas?
Merci pour ta réponse.
tu fais saisir quelque chose dans une TextBox, et tu fais contrôler la saisie à partir de la liste de la ListBox, c'est ça ?
Plus exact au fur à mesure que je saisie dans TextBox en fonction de la saisie progressivement la correspondance de la ListBox et mise en surbrillance.
En fait je ne veux pas utiliser combo box.
C'est le besoin que je ne vois pas vraiment.
Pour moi ça passe avec ComboBox, mais pas pour ceux qui travaille sur l'interface que j'ai fait.
Je suis toujours à la recherche d'une solution. Je vais arriver un jour.
Encore une fois merci pour ton message.
lami20j
comment tu vas?
Merci pour ta réponse.
tu fais saisir quelque chose dans une TextBox, et tu fais contrôler la saisie à partir de la liste de la ListBox, c'est ça ?
Plus exact au fur à mesure que je saisie dans TextBox en fonction de la saisie progressivement la correspondance de la ListBox et mise en surbrillance.
En fait je ne veux pas utiliser combo box.
C'est le besoin que je ne vois pas vraiment.
Pour moi ça passe avec ComboBox, mais pas pour ceux qui travaille sur l'interface que j'ai fait.
Je suis toujours à la recherche d'une solution. Je vais arriver un jour.
Encore une fois merci pour ton message.
lami20j
Bonjour,
alors je relisait le code d'origine et la ça ma frappé !
la déclaration de la deuxième API comporte un manque
selon tout le reste !
il manque le ByVal du dernier argument.
comme je t'ai suggéré, la définition du typage est importante.
ByVal : Valeur par défaut qui fait en sorte de ne pas modifier
la variable lors du retour, de façon implicite valeur par défaut
écrite ou pas
ByRef : La variable sera modifier au retour dans l'appelant.
Si tous les autres sont spécifier, il faut le faire pour lui aussi,
si tu attends une valeur modifier sur un argument, il doit être
typé ByREF, car pour l'API le VBA est l'appelant, tu passe une
variable même vide, et au retour elle a un contenu, dans la
définition de la procédure, elle sera déclaré ByRef.
vérifie, je crois qu'il pourrait y avoir une particularité pour VBA !
et peut-être aussi le mot [externe/public] dans la déclaration !
Lupin
alors je relisait le code d'origine et la ça ma frappé !
la déclaration de la deuxième API comporte un manque
selon tout le reste !
il manque le ByVal du dernier argument.
comme je t'ai suggéré, la définition du typage est importante.
ByVal : Valeur par défaut qui fait en sorte de ne pas modifier
la variable lors du retour, de façon implicite valeur par défaut
écrite ou pas
ByRef : La variable sera modifier au retour dans l'appelant.
Si tous les autres sont spécifier, il faut le faire pour lui aussi,
si tu attends une valeur modifier sur un argument, il doit être
typé ByREF, car pour l'API le VBA est l'appelant, tu passe une
variable même vide, et au retour elle a un contenu, dans la
définition de la procédure, elle sera déclaré ByRef.
vérifie, je crois qu'il pourrait y avoir une particularité pour VBA !
et peut-être aussi le mot [externe/public] dans la déclaration !
Lupin
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Re,
j'ai essayé avec ByVal mais ça ne marche toujours pas.
Pour l'instant j'ai contourné le problème :
j'ai mis un ComboBox (merci Armojax pour la reprise sur Combo que j'ai laissé tombé ) sur la feuille dont j'ai caché la flèche et j'utilise
Merci à Lupin.A ( c'est toi Lupin?!) et Armojax
j'ai essayé avec ByVal mais ça ne marche toujours pas.
Pour l'instant j'ai contourné le problème :
j'ai mis un ComboBox (merci Armojax pour la reprise sur Combo que j'ai laissé tombé ) sur la feuille dont j'ai caché la flèche et j'utilise
Private Sub cbnom_Change() On Error Resume Next lstnom.Selected(cbnom.ListIndex) = True End SubPour l'instant j'ai ce que j'ai voulais mais en utilisant un petiti bidouillage.
Merci à Lupin.A ( c'est toi Lupin?!) et Armojax
je vais tester ce que tu m'as donné et je tiendrai au courant.
J'ai oublié de te dire que en VB ça fonctionne, donc je me suis demandé si vraiment Excel accepte les API ou pas.
Sinon je serai obligé de créer moi même une fonction pour ça.
A+
lami20j