【问题标题】:Excel VBA - make sure Numlock is always ONExcel VBA - 确保 Numlock 始终打开
【发布时间】:2021-07-18 13:42:11
【问题描述】:

我知道这已经引起了人们的注意,但我无法解决它。 我有一个调用 sub 的按钮,在该 sub 中我想确保 numlock 始终处于打开状态。 第一次,即如果 numlock 关闭,它会打开它。如果它已经打开,单击按钮一次或两次会使数字锁定保持打开状态,但单击第三次会关闭数字锁定。再次单击可将其关闭。再次单击将其再次打开。所以每3次点击它就会关闭它。我不明白如何解决它。我有 Excel 2019 位和 Windows 10 64 位。代码如下:

Private Declare PtrSafe Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
Private Const kCapital = 20
Private Const kNumlock = 144

Public Function CapsLock() As Boolean
    CapsLock = KeyState(kCapital)
End Function

Public Function NumLock() As Boolean
    NumLock = KeyState(kNumlock)
End Function

Private Function KeyState(lKey As Long) As Boolean
    KeyState = CBool(GetKeyState(lKey))
End Function


Public Sub ToggleNumlock(choice As Boolean)
Application.Volatile

If choice = True Then
    If NumLock = False Then SendKeys "{NUMLOCK}", True
Else
    If NumLock = True Then SendKeys "{NUMLOCK}", True

End If
End Sub

在按钮触发的子中我有:

Application.SendKeys "{F2}"

就在我拥有之后

      If NumLock = False Then
       ToggleNumlock (True)
      End If

会不会是 Sendkeys 引起了麻烦? 因为我需要它,有解决方法吗? 谢谢。

更新我的代码:

ActiveSheet.Range(CurrentCell).Value = "=" 
ActiveSheet.Range(CurrentCell).Select
Application.SendKeys "{F2}", True
Application.SendKeys "=", True
Application.SendKeys "{F2}"

我删除了所有关于 numlock on off 等的代码,并尝试这样做至少现在可以在我的机器上工作:我只需按两次键。明天我会在我的办公室机器上检查一下。

2021 年 7 月 19 日更新 在我的办公室(Windows 64 本地化意大利语,Excel 2010)中,我遇到了同样的问题,它可以切换数字锁,但数字键盘上的逗号也变成了一个点(在意大利,它是 3,14 而不是 3.14)。我放弃。感谢所有试图帮助我的人。 MS 必须真正修复 sendkeys。

【问题讨论】:

  • 当您搜索“vba sendkeys numlock closed”时会有很多点击。所以Sendkeys 似乎关闭了Numlock,即使你发送了另一个按键
  • 我看不到您在更新的代码中使用NumLockOn 的位置,也不了解您的代码的用途。你介意解释一下吗?

标签: excel vba sendkeys num-lock


【解决方案1】:

基于此article,您可以使用以下代码打开 Num Lock

Option Explicit
'https://www.vbarchiv.net/tipps/details.php?id=563

Private Declare PtrSafe Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer


Private Declare Sub keybd_event Lib "user32" ( _
    ByVal bVk As Byte, _
    ByVal bScan As Byte, _
    ByVal dwFlags As Long, _
    ByVal dwExtraInfo As Long)
 
Private Const VK_NUMLOCK = &H90
Private Const KEYEVENTF_KEYUP = &H2

Sub pressNumLock()
    ' press NUM-Lock drücken
    ' first key down and then key-up
    keybd_event VK_NUMLOCK, 1, 0, 0
    keybd_event VK_NUMLOCK, 1, KEYEVENTF_KEYUP, 0
End Sub

Sub NumLockOn()
    ' activate NUM-Lock (in case it is not activated)
    If Not (GetKeyState(vbKeyNumlock) = 1) Then
        pressNumLock
    End If
End Sub

【讨论】:

  • 我用这个代码替换了我之前的代码,但它一直在打开和关闭数字锁定(现在每点击 2 次)。真烦人。
  • 我很害怕,但您必须更具体并发布调整后的代码。我发布的代码对我来说没有问题。正如我在对您的帖子的评论中所说,Sendkeys 将关闭“Numlock”,即使您发送另一个按键也是如此。这只是意味着你必须避免使用Sendkeys
  • 代码完美运行。如果您不使用NumLockOn Sub 而使用pressNumLock,则可能会产生问题... :) 已投票。只需在 Sub keybd_event Lib... 之前插入 PtrSafe 即可。我还会建议在SetNumLock 中更改NumLockOn 名称。
  • 单独为 PtrSafe 加前缀并不能涵盖所有情况(即指向 → 句柄或 → 内存位置的指针需要 LongPtr 类型)。 - keybd_event 的 Afaik VBA7 PtrSafe API 声明将需要 dwExtraInfo 作为 LongPtr,而不是 Long 类型;即使在函数pressNumLock() 中将其作为0 参数传递,也需要进行转换。
  • 根据this article keybd_event 已过时,您应该改用SendInput
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 2019-05-25
  • 2020-08-12
  • 1970-01-01
相关资源
最近更新 更多