在宏运行结束时打开numlock



什么代码执行:我有一个将鼠标移动屏幕周围的代码,将printscreens移动并粘贴到Excel。

问题:出于某种原因,我的代码总是(绝对没有例外)在每次运行后关闭Numlock键。

我到目前为止尝试过的内容:我四处搜索并找到了Sendkeys(numlock),这在理论上有效(尽管这对用户来说似乎是非常有问题的)。

我想做的:我想在每个宏运行后打开numlock,

obs1:我不知道是什么原因导致宏首先将其关闭。修复引起这一点的内容将是理想的选择,但是由于我不知道问题是什么,所以我首先想使我的代码功能功能。我将在找到一种打开numlock键的方法后立即对此进行努力。

问题:我可以使用sendkeys做到这一点吗?我是否正确使用它?有更好的方法吗?

obs2:由于它是一个更大的代码,一旦解决了,我将在整个代码中发布另一个问题,然后介绍引起问题的原因。

代码我试图起诉以打开numlock:

Application.Sendkeys (NUMLOCK)

也尝试了:

Application.Sendkeys ("NUMLOCK")

Application.Sendkeys {NUMLOCK}

您可以使用几个Windows API调用直接设置键状态。从MSDN页面移植以供Keybd_event函数:

移植
#If VBA7 Then
    Private Declare PtrSafe Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, _
                                                              ByVal dwFlags As LongPtr, ByVal dwExtraInfo As LongPtr)
    Private Declare PtrSafe Function GetKeyboardState Lib "user32.dll" (ByVal lpKeyState As LongPtr) As Boolean
#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)
    Private Declare Function GetKeyboardState Lib "user32.dll" (ByVal lpKeyState As Long) As Boolean
#End If  
Private Const KEYEVENTF_EXTENDEDKEY As Long = &H1
Private Const KEYEVENTF_KEYUP As Long = &H2
Private Const VK_NUMLOCK As Byte = &H90
Private Const NumLockScanCode As Byte = &H45
Private Sub ToggleNumlock(enabled As Boolean)
    Dim keystate(255) As Byte
    'Test current keyboard state.
    GetKeyboardState (VarPtr(keystate(0)))
    If (Not keystate(VK_NUMLOCK) And enabled) Or (keystate(VK_NUMLOCK) And Not enabled) Then
        'Send a keydown
        keybd_event VK_NUMLOCK, NumLockScanCode, KEYEVENTF_EXTENDEDKEY, 0&
        'Send a keyup
        keybd_event VK_NUMLOCK, NumLockScanCode, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0&
    End If
End Sub

这样称呼:

Sub Example()
    'Turn Numlock off.
    ToggleNumlock False
    'Turn Numlock on.
    ToggleNumlock True
End Sub

首先,将以下代码复制并粘贴到Excel Sheet的模块中(例如:-module-1)...

Private Declare 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

然后,将以下内容复制并粘贴在您的工作表代码中(例如:-sheet1(code))...

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
      Range("XFD1").FormulaR1C1 = "=NumLock()"
      If Range("XFD1").Value = "FALSE" Then
      SendKeys "{NUMLOCK}"
      Else
      End If
      End Sub

现在冷却!!!对于您制作的每个选择,Excel会刷新本身,并确保NumLock始终处于启动状态。如果需要,请替换" capslock",而不是numlock。

谢谢。Sashi Elit:)

我发现了这一解决方案的最佳状态,并且不会干扰numlock。将下面的代码放入模块中,然后从项目中的任何地方调用它。脚本对象覆盖vba中的sendkeys。

Public Sub Sendkeys(text as variant, Optional wait As Boolean = False)
   Dim WshShell As Object
   Set WshShell = CreateObject("wscript.shell")
   WshShell.Sendkeys cstr(text), wait
   Set WshShell = Nothing
End Sub 

我在下面的线程中找到了它:

sendkeys()权限拒绝了Visual Basic

中的错误

我尝试了所有建议,直到我注意到它不是(numlock)而是{numlock}。这对我有用。

sub numlock()sendkeys" {numlock}"结束子

您几乎拥有它!正确的编码是:application.sendkeys(" {numlock}")

最新更新