API - "SendMessage" - dans Excel

Résolu
lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   -  
lami20j Messages postés 21506 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
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

5 réponses

  1. Lupin
     
    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

    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
    0
    1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      Merci beaucoup Lupin,

      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
      0
  2. 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 :
    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
    0
  3. Lupin
     
    re:

    désolé je ne puis éditer le message (mon compte est bousillé).

    CStr(txtnomsearch.Text)

    Lupin
    0
    1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      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
      0
  4. Armojax Messages postés 1863 Date d'inscription   Statut Membre Dernière intervention   1 529
     
    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.
    0
    1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      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
      0
    2. Utilisateur anonyme
       
      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
      0
      1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571 > Utilisateur anonyme
         
        Salut Lupin,

        je vais tester.

        je crois qu'il pourrait y avoir une particularité pour VBA !
        C'est possible, puisque les API je l'ai récupéré depuis une viseuneuse API donc il n'y a pas d'erreurs.

        Merci,

        lami20j
        0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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
    Private Sub cbnom_Change()
       On Error Resume Next
       lstnom.Selected(cbnom.ListIndex) = True
    End Sub
    Pour l'instant j'ai ce que j'ai voulais mais en utilisant un petiti bidouillage.

    Merci à Lupin.A ( c'est toi Lupin?!) et Armojax
    0