IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Solution au bug SendKeys / Numlock


Sujet :

Macros et VBA Excel

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 231
    Points : 93
    Points
    93
    Par défaut Solution au bug SendKeys / Numlock
    Bonjour à tous.

    Auriez-vous une solution fiable au bug (bien connu) de l'utilisation du sendkeys qui active ou désactive le Numlock ?

    Je souhaite qu'une liste déroulante s'ouvre au premier clic et j'utilise le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Not Intersect(Range("B4:B9, B22:B25, B36:B39, B43:B45, B53:B56, B67:B70, B82:B83, B99:B103, A131:A131"), Target) Is Nothing And Target.Count = 1 Then
    Application.SendKeys "%{DOWN}"
    End If
    End Sub
    J'ai testé sans succès les solutions suivantes :

    Doevents :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Not Intersect(Range("B4:B9, B22:B25, B36:B39, B43:B45, B53:B56, B67:B70, B82:B83, B99:B103, A131:A131"), Target) Is Nothing And Target.Count = 1 Then
    Application.SendKeys "%{DOWN}"
    Doevents
    End If
    End Sub
    En fonction de l'état de la touche Numlock :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Not Intersect(Range("B4:B9, B22:B25, B36:B39, B43:B45, B53:B56, B67:B70, B82:B83, B99:B103, A131:A131"), Target) Is Nothing And Target.Count = 1 Then
    Application.SendKeys "%{DOWN}"
    If GetKeyState(vbKeyNumlock) = 1 Then
    Application.SendKeys "{NUMLOCK}"
    End If
    End If
    End Sub
    Pouvez-vous m'aider ? L'ouverture en un clic du menu déroulant m'est vraiment très utile.

    Merci et excellente fin de journée à tous.

  2. #2
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 379
    Points
    20 379
    Par défaut
    salut ,

    1 éviter les "strings" à rallonge dans le code , cela l'obscurcit; dans l'instruction Range

    2 pour répondre à la question , au pif essayer de voir si en faisant du subclassing.
    Il faut essayer d'obtenir le handle de l'onglet avec l'API GetWindowLong et de gérer les instructions SendKeys.
    Mais c'est une méthode peu orthodoxe...

  3. #3
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut
    Bonjour !

    Citation Envoyé par atk_49 Voir le message
    Auriez-vous une solution fiable au bug (bien connu) de l'utilisation du sendkeys qui active ou désactive le Numlock ?
    Déjà ce n'est pas un bug, tout au plus une constatation, un désagrément …

    La solution est simple : ne pas utiliser les SendKeys du VBA mais le SendKeys du Shell de Windows !
    Parmi les nombreux exemples de ce forum voir cette discussion

    _________________________________________________________________________________________________________
    Je suis Paris, Istanbul, Berlin, Nice, Bruxelles, Charlie, …
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  4. #4
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut RE
    RE
    BONSOIR
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.SendKeys "%{DOWN}"
    pourquoi ne pas faire un "activecell.offset(1,0).activate ou select???????????????
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  5. #5
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 422
    Points
    12 422
    Par défaut
    Bonjour patricktoulon
    pourquoi ne pas faire un "activecell.offset(1,0).activate ou select???????????????
    pour au moins deux bonnes raisons :
    - cela ne déploierait pas sa liste déroulante
    - la nouvelle sélection résultante redéclencherait l'évènement selection_change, etc, etc ...
    Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
    Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .

    ****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...

    Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 231
    Points : 93
    Points
    93
    Par défaut
    Bonjour et merci à tous pour vos réponses.

    Voici le code définitif et qui fonctionne dans mon cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    If Not Intersect(Range("B4:B9, B22:B25, B36:B39, B43:B45, B53:B56, B67:B70, B82:B83, B99:B103, A131:A131"), Target) Is Nothing And Target.Count = 1 Then
    Application.SendKeys "%{down}"
    DoEvents
    Application.SendKeys ("{NUMLOCK}"), True
    Application.SendKeys ("{NUMLOCK}"), True
    End If
    Niveau Orthodoxie on reviendra, mais ça marche !

    Bon week-end !

  7. #7
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut




    Ou en une seule ligne de code via le Shell SendKeys comme pourtant indiqué en clair dans le code du lien ‼
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  8. #8
    Expert éminent sénior
    Avatar de kiki29
    Homme Profil pro
    ex Observeur CGG / Analyste prog.
    Inscrit en
    Juin 2006
    Messages
    6 132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : ex Observeur CGG / Analyste prog.

    Informations forums :
    Inscription : Juin 2006
    Messages : 6 132
    Points : 11 274
    Points
    11 274
    Par défaut
    Salut, à tenter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Dim Wsh As Object
     
        Set Wsh = CreateObject("WScript.Shell")
        Wsh .SendKeys "%{DOWN}", True
        Set Wsh = Nothing

  9. #9
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par atk_49 Voir le message
    Bonjour et merci à tous pour vos réponses.

    Voici le code définitif et qui fonctionne dans mon cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    If Not Intersect(Range("B4:B9, B22:B25, B36:B39, B43:B45, B53:B56, B67:B70, B82:B83, B99:B103, A131:A131"), Target) Is Nothing And Target.Count = 1 Then
    Application.SendKeys "%{down}"
    DoEvents
    Application.SendKeys ("{NUMLOCK}"), True
    Application.SendKeys ("{NUMLOCK}"), True
    End If
    Niveau Orthodoxie on reviendra, mais ça marche !

    Bon week-end !
    surtout que le soucis est aleatoire des fois ca coupe numlock des fois pas donc tes deux lignesnumlock ne font que repeter le problemesi numlock est en mode off tu le rallume et tu tu le re rebloque
    shell un point c'est tout
    bien que je ne vois toujours pas l'utilité du sendkeys dans ce cas present

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Not Intersect(Range("B4:B9, B22:B25, B36:B39, B43:B45, B53:B56, B67:B70, B82:B83, B99:B103, A131:A131"), Target) Is Nothing And Target.Count = 1 Then target.offset(1,0).select
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  10. #10
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 231
    Points : 93
    Points
    93
    Par défaut
    @kiki29

    Merci avec un an de retard, en effet la méthode via le shell ne provoque plus le problème.


  11. #11
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    bonjour
    a ben oui pour le coup tu a pris ton temps
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  12. #12
    Candidat au Club
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2022
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Novembre 2022
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Bonjour,

    J'ai essayé la méthode shell avec :
    CreateObject("WScript.Shell").SendKeys "{F2}"

    Mais j'ai toujours le problème qui désactive/réactive Numlock

    Un grand merci pour votre aide (ça fait 5h que je cherche la réponse...)

  13. #13
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 101
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 101
    Points : 1 621
    Points
    1 621
    Par défaut
    Mouais, heu ....

    D'une part évite le déterrage.
    D'autre part, essayer de détourner les fonctionnalités standard, ce n'est jamais une bonne idée.

  14. #14
    Rédacteur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2013
    Messages
    947
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Août 2013
    Messages : 947
    Points : 4 058
    Points
    4 058
    Par défaut
    Citation Envoyé par GuillaumeG6916 Voir le message
    Mais j'ai toujours le problème qui désactive/réactive Numlock

    bonjour,
    c'est curieux que personne n'ait répondu car la solution est bien connue : il suffit d'utiliser les API.
    Dans votre cas utilisez la fonction SetNumLock(False) pour désactiver le clavier numérique ou SetNumLock(True) pour l'activer.

    Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    Option Explicit
     
    ' API Pour la gestion des touches du clavier:
    Private Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
    Private Declare PtrSafe Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    Private Declare PtrSafe Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
     
    ' Constantes pour la gestion des touches du clavier:
    Private Const VK_NUMLOCK = &H90
    Private Const VK_CAPITAL = &H14
    Private Const KEYEVENTF_EXTENDEDKEY = &H1
    Private Const KEYEVENTF_KEYUP = &H2
     
    '------------------------------------------------------------------------------------------------
    Private Sub SetKeyState(ByVal Key As Long, ByVal State As Boolean)
    '------------------------------------------------------------------------------------------------
        keybd_event Key, MapVirtualKey(Key, 0), KEYEVENTF_EXTENDEDKEY Or 0, 0
        keybd_event Key, MapVirtualKey(Key, 0), KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0
        If Key = 20 And State = False Then ' cas particulier pour VK_CAPITAL
            keybd_event 16, 0, 0, 0
            keybd_event 16, 0, 2, 0
        End If
    End Sub
     
    '------------------------------------------------------------------------------------------------
    Public Sub SetNumLock(Etat As Boolean)
    '------------------------------------------------------------------------------------------------
    ' Etat = True : Active le clavier numérirque.
    ' Etat = False : Désactive le clavier numérique.
    '------------------------------------------------------------------------------------------------
    While GetKeyState(VK_NUMLOCK) = 1 + Etat
        SetKeyState VK_NUMLOCK, Etat
        DoEvents
    Wend
    End Sub
     
    '------------------------------------------------------------------------------------------------
    Public Sub SetCapital(Etat As Boolean)
    '------------------------------------------------------------------------------------------------
    ' Etat = True : Active le mode majuscule.
    ' Etat = False : Désactive le mode majuscule.
    '------------------------------------------------------------------------------------------------
    While GetKeyState(VK_CAPITAL) = 1 + Etat
        SetKeyState VK_CAPITAL, Etat
        DoEvents
    Wend
    End Sub
    '------------------------------------------------------------------------------------------------
    '------------------------------------------------------------------------------------------------




    Bonne programmations.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Encodage] Solution pour éviter le bug "À"
    Par loribac dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 04/12/2013, 21h57
  2. Bug de refresh : Solution de contournement existe-elle ?
    Par sinfoni dans le forum Composants FMX
    Réponses: 4
    Dernier message: 11/04/2012, 08h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo