XL 2019 Perte du NumLock

fanch55

XLDnaute Barbatruc
Bonsoir à Tous,

Cela fait des années que je recherche à résoudre la perte du "NumLock" ou "VerrNum" sur le Clavier.

Quand je clique sur une cellule qui a une Validation de Données type Liste,
j'envoie un SendKeys "%{down}%", True sans attendre que l'utilisateur clique sur la flèche de dropdown.
Systématiquement, cela provoque la désactivation du NumLock .

J'ai essayé les api getkeyboardstate et autres getkeystate et tenter d'appliquer des
SendKeys "{NUMLOCK}" avec true ou pas, cela ne fonctionne jamais correctement .

Si quelqu'un a une astuce infaillible et non aléatoire pour rétablir le numlock, je suis preneur ...
 
Solution
Bonsoir fanch55;

Je suis étonné que vous découvriez seulement maintenant cet effet de Application.SendKeys.

Qui date de Excel 2007 ou 2010.

Le problème se règle en utilisant CreateObject("WScript.Shell").SendKeys.

Faites une recherche sur mes posts avec le mot clé SendKeys, il y en a un paquet.

A+

patricktoulon

XLDnaute Barbatruc
Je comprends pas !
65 c'est le code de 'A' pas de 'a'. Et pourtant ça affiche 'a'. C'est quoi le truc ?
c'est le code asc de "A" mais aussi le code de la touche avec la lettre "A"
ne pas confondre le code asc d'une lettre et le code d'une touche du clavier même si en effet le asc de "A" est bien 65
là c'est le code touche que l'on envoie a la fonction car c'est ce code qu'attend l'api et comme ça qu'elle l’interprète
teste dans un textbox avec le "A" majuscule et minuscule
VB:
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
MsgBox KeyCode
End Sub

Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
MsgBox KeyAscii
End Sub
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Ok, c'est donc un Virtual Code -> https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
Donc c'est majuscules si le clavier est en majuscules et minuscules sinon. Et si on veut contrôler faut d'abord déterminer l'état de le touche Caps Lock et éventuellement envoyer une Shift key avant.

Quant au Doevents, ça m'échappe totalement pourquoi il change la donne. Mais c'est un fait qu'il la change.
 

Dudu2

XLDnaute Barbatruc
si tu veux maj tu envoie un shift
Oui j'ai compris. Mais ça dépend aussi de l'état de la CAPS LOCK key (VK_CAPITAL 0x14).

J'ai remarqué que, de manière surprenante, cette méthode n'est pas synchrone.
Et là, avec ExecuteExcel4Macro, on ne peut pas utiliser le DoEvents pour attendre la fin, contrairement aux autres méthodes (voir Post #10) car en l'occurrence le DoEvents a, pour une raison totalement inconnue, un effet délétère sur les touches entrées.
Il faut alors utiliser l'API (voir post suivant) pour pouvoir utiliser le DoEvents.

Dans l'exemple [B1].Value = "aaa" (valeur précédente de [A1]) et pas "abc" (valeur actuelle de [A1])
VB:
Function Xsendkeys(key, sens)
    ExecuteExcel4Macro ("CALL(""user32"",""keybd_event"",""JJJJJ""," & key & ", " & 1 & ", " & sens & ", " & 0 & ")")
End Function

Sub a()
    [A1].Value = "aaa"
    [B1].ClearContents
    [A1].Select
    Xsendkeys 65, 0 'on apui sur la touche a
    Xsendkeys 65, &H2 'on relache la touche a
    Xsendkeys 66, 0 ' on apui sur la touche b
    Xsendkeys 66, &H2 'on relache la touche b
    Xsendkeys 67, 0 ' on apui sur la touche c
    Xsendkeys 67, &H2 'on relache la touche c
    Xsendkeys 13, 0 ' on apui sur la touche enter
    Xsendkeys 13, &H2 'on relache la touche enter
    [B1].Value = [A1].Value
End Sub
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Pour info tu peux mettre 0 au lieu de 1 dans le Scan Code (2ème argument)
Et en utilisant KEYEVENTF_EXTENDEDKEY (&H1] ça marche aussi pour appuyer sur la touche.
VB:
Xsendkeys 65, &H1 'on apui sur la touche a
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
enlève le doevents tu va voir
L'effet délétère du DoEvents ne se produit qu'avec l'ExecuteMacro4Excel.
En API native, on n'a pas ce problème. Sans compter que l'API native va en gros 4 fois plus vite.
VB:
#If VBA7 Then
    Private Declare PtrSafe Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, _
                                                              ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
#Else
    Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, _
                                                      ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
#End If

Function Xsendkeys(Key As Byte, Sens As Long)
    Call keybd_event(Key, 0, Sens, 0)
    'ExecuteExcel4Macro ("CALL(""user32"",""keybd_event"",""JJJJJ""," & Key & ", " & 0 & ", " & Sens & ", " & 0 & ")")
    DoEvents
End Function

Sub a()
    [A1].ClearContents
    [A1].Select
    Xsendkeys 65, &H1 'on apui sur la touche a
    Xsendkeys 65, &H2 'on relache la touche a
    Xsendkeys 66, &H1 ' on apui sur la touche b
    Xsendkeys 66, &H2 'on relache la touche b
    Xsendkeys 67, &H1 ' on apui sur la touche c
    Xsendkeys 67, &H2 'on relache la touche c
    Xsendkeys 13, &H1 ' on apui sur la touche enter
    Xsendkeys 13, &H2 'on relache la touche enter
End Sub
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Bonjour @patricktoulon,
J'espère que tu vas bien ce matin.
Je vais moi aussi te contredire, car je ne crois pas que la puissance CPU de PCs différents change fondamentalement le rapport de temps d'exécution entre ces 2 méthodes.
De plus je vois mal un ExecuteExcelMacro qui "emballe" un appel à une fonction API aller plus vite que l'appel direct à la fonction API.

En post suivant voici mon fichier de test avec 1 bouton pour chaque méthode basé sur une centaine d'appels successifs et sans les DoEvents pour que ce soit représentatif.
Je t'invite (et tout lecteur volontaire) à essayer de cliquer une dizaine de fois sur chaque bouton et constater la différence.
 
Dernière édition:

MJ13

XLDnaute Barbatruc
Bonjour à tous

En général quand j'ai un problème avec sendkeys qui désactive le clavier numérique, j'utilise ce code:

VB:
Sub AA()
SendKeys ("AA~")
End Sub
Sub AB()
SendKeys ("AB~")
Réactive_Clavier_Numérique
End Sub
Sub ABC()
SendKeys ("A~")
SendKeys ("B~")
SendKeys ("C~")
Réactive_Clavier_Numérique
End Sub
Sub Réactive_Clavier_Numérique()
With Application
          DoEvents
          Application.SendKeys ("{NUMLOCK}"), True
          Application.SendKeys ("{NUMLOCK}"), True
    End With
End Sub
 

Dudu2

XLDnaute Barbatruc
Tiens, je t'ai fait un joli tableau pour comparer les résultats, leurs moyennes et le rapport.
J'arrive le plus souvent à un rapport de 1 à 7-9 et pas de 1 à 4 comme je l'avais dit précédemment.
 

Pièces jointes

  • Comparaison API & ExecuteExcel4Macro sur keybd_event.xlsm
    29.2 KB · Affichages: 6
Dernière édition:

Dudu2

XLDnaute Barbatruc
D'une part je vois pas quelle mémoire tu veux vider et d'autre part, en utilisation réelle, personne ne va "vider la mémoire" avant d'utiliser ces fonctions. A la limite vider une petite bière avant de faire le test, oui, ça m'arrive
1629375136628.gif
 

Dudu2

XLDnaute Barbatruc
Les SendKeys "{NUMLOCK}" ça marche quand ça veut bien. J'en ai fait l'expérience et @fanch55 aussi apparemment.

Si on doit gérer le NUMLOCK il vaut mieux s'en remettre à la fonction du Post #10 qui utilise l'API.

Pour un SendKeys, c'est le CreateObject("wscript.shell").SendKeys (Keys) qui est le plus simple et n'a pas d'impact sur le NUMLOCK.

Et si on a besoin d'une synchro entre l'envoi des touches et le code, il suffit alors d'ajouter un DoEvents juste après. Voir le Post #10 pour les explications à ce sujet.
 
Dernière édition:

Statistiques des forums

Discussions
312 279
Messages
2 086 730
Membres
103 380
dernier inscrit
prolofief