SendKeys 正在通过 Access 表单中的 VBA 代码弄乱我的 NumLock 键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25977933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 08:58:13  来源:igfitidea点击:

SendKeys is messing with my NumLock key via VBA code in Access form

vbaaccess-vbams-access-2007sendkeys

提问by user12059

I have the following code for an Access form. It appears as if the SendKeysis messing with my NumLockkey by toggling it on and off as I open and close the form.

我有以下访问表单的代码。当我打开和关闭表单时,它似乎通过打开和关闭它SendKeys来弄乱我的NumLock密钥。

For perfectly valid reasons which I don't want to get into, I really do not want to completely hide the ribbon (I want the pull down menus still accessible) so the DoCmd.ShowToolbarcommand is not my preferred way of doing it.

出于我不想进入的完全有效的原因,我真的不想完全隐藏功能区(我希望下拉菜单仍然可以访问)所以DoCmd.ShowToolbar命令不是我的首选方式。

Does anyone have any suggestions as to how I can modify the code below to accomplish what I want using the SendKeyscommand?

有没有人对我如何修改下面的代码以使用该SendKeys命令完成我想要的操作有任何建议?

Using Access 2007 so the command

使用 Access 2007 所以命令

CommandBars.ExecuteMso "MinimizeRibbon"

is not available to me.

对我不可用。

By the way, database will be distributed so solution must be contained within database.

顺便说一下,数据库将是分布式的,因此解决方案必须包含在数据库中。

Private Sub Form_Close()

' Unhide navigation pane
    DoCmd.NavigateTo "acNavigationCategoryObjectType"
    DoCmd.Maximize

' Maximize the ribbon
RibbonState = (CommandBars("Ribbon").Controls(1).Height < 75)

Select Case RibbonState
    Case True
        SendKeys "^{F1}", True
    Case False
        'Do nothing, already maximized
End Select
End Sub

Private Sub Form_Load()
' Hide navigation pane
    DoCmd.NavigateTo "acNavigationCategoryObjectType"
    DoCmd.Minimize
Debug.Print Application.CommandBars.Item("Ribbon").Height
' Minimize ribbon
RibbonState = (CommandBars("Ribbon").Controls(1).Height < 100)

Select Case RibbonState
    Case True
        'Do nothing, already minimized
    Case False
            SendKeys "^{F1}", False
End Select
End Sub

回答by icebird76

It's a bug in Microsoft VBA. But there is a workaround.

这是 Microsoft VBA 中的一个错误。但是有一个解决方法。

Use F8to run through the macro and find where it turns it off. It's usually after a SendKeys.

使用F8通过宏观运行,并找到它关闭它。它通常在SendKeys.

Then add an Sendkeys "{NUMLOCK}", Trueafter the line to reverse the effect.

然后Sendkeys "{NUMLOCK}", True在该行后添加一个 以反转效果。

If you can't find it, just add it at the end and when it finishes, it will go back. Hopefully, if you add it during the show/hide process, it will work.

如果你找不到它,只需在最后添加它,当它完成时,它会返回。希望如果您在显示/隐藏过程中添加它,它将起作用。

回答by omari

This is caused by :

这是由以下原因引起的:

Sendkeys "any key", False

Instead of Falseas second parameter, use True.

而不是False作为第二个参数,使用True.

回答by BTHymaner

I had similar issue and I found solution on some vba forum. Instead of buggy Sendkeys you can simulate kyes like this.

我有类似的问题,我在一些 vba 论坛上找到了解决方案。您可以像这样模拟 kyes,而不是有缺陷的 Sendkeys。

    Option Explicit
'//WIN32API Declare
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

'//WIN32API Constant

Public Const KEYEVENTF_EXTENDEDKEY = &H1
Public Const KEYEVENTF_KEYUP = &H2
Public Const VK_CONTROL = &H11
Public Const VK_SHIFT = &H10
Public Const VK_F6 = &H75

Public Function PreviousTab()
    keybd_event VK_CONTROL, 0, 0, 0
    keybd_event VK_SHIFT, 0, 0, 0
    keybd_event VK_F6, 0, 0, 0
    keybd_event VK_F6, 0, KEYEVENTF_KEYUP, 0
    keybd_event VK_SHIFT, 0, KEYEVENTF_KEYUP, 0
    keybd_event VK_CONTROL, 0, KEYEVENTF_KEYUP, 0
End Function

Other keys can be found here vba forumThis "previousTab" function just send Control+Shift+F6 key.

其他键可以在这里找到vba 论坛这个“previousTab”功能只是发送 Control+Shift+F6 键。

回答by RodB

This line caused my problem:

这条线引起了我的问题:

Application.SendKeys "%s"

SOLVED by changing to this:

通过更改为以下解决方案:

Application.SendKeys "{NUMLOCK}%s"

There's no difference between adding {NUMLOCK}at the beginning or end of the string.

{NUMLOCK}在字符串的开头或结尾添加没有区别。

回答by Petr Michl

The SendKeys() function that is built-in VBA has really a side effect that causes NumLock to be deactivated. But you can use a workaround and call another implementation of the same function that is a part of WSCRIPT component (a part of Windows operating system). The following sample code shows, how a reference to this component can be made and then its method called:

VBA 内置的 SendKeys() 函数确实具有导致 NumLock 停用的副作用。但是您可以使用一种解决方法并调用作为 WSCRIPT 组件(Windows 操作系统的一部分)一部分的相同函数的另一个实现。以下示例代码显示了如何引用此组件,然后调用其方法:

Set WshShell = CreateObject("WScript.Shell")
WshShell.SendKeys "^g", True

This way, you get the same functionality (calling Ctrl-G keyboard shortcut in the example), but there is no issue with NumLock in this case.

这样,您可以获得相同的功能(在示例中调用 Ctrl-G 键盘快捷键),但在这种情况下 NumLock 没有问题。

回答by user6788933

After trying many solutions. The most solid seems to be on the link below. Paste it to a Module.

在尝试了许多解决方案之后。最可靠的似乎在下面的链接上。将其粘贴到模块中。

http://access.mvps.org/access/api/api0046.htm

http://access.mvps.org/access/api/api0046.htm

回答by Mendel Lowy

Right after your SendKeys statement add these 2 lines:

在 SendKeys 语句之后添加以下两行:

DoEvents
SendKeys "{NUMLOCK}{NUMLOCK}"

回答by technoman23

When you do a final sendKeys command in your code, adding in {NUMLOCK} to the statement may do the trick, as noted by RodB and iceBird76. But this is not a good coding practice, and here is why: if anything is different from one time to the next when you run the macro, it may or may not work. I know this because I was experiencing a similar issue myself. When I would do a sendKeys command at the end of my program, sometimes the Num Lock would stay on, but other times it would stay off, just depending on certain variables in my spreadsheet (regardless of whether or not I included {NUMLOCK} in my last SendKeys statement).
I won't get into the details of my own variables, but the point is that to build a program/macro that will keep your Num Lock on consistently, you need to FIRST TEST TO SEE IF THE NUM LOCK IS ON OR OFF, then execute code based upon the present condition.

正如 RodB 和 iceBird76 所指出的那样,当您在代码中执行最后的 sendKeys 命令时,将 {NUMLOCK} 添加到该语句可能会起作用。但这不是一个好的编码习惯,原因如下:如果在运行宏时一次又一次有任何不同,它可能会也可能不会起作用。我知道这一点,因为我自己也遇到了类似的问题。当我在程序结束时执行 sendKeys 命令时,有时 Num Lock 会保持打开状态,但有时它会保持关闭状态,这取决于电子表格中的某些变量(无论我是否包含 {NUMLOCK}我的最后一个 SendKeys 语句)。
我不会详细介绍我自己的变量,但关键是要构建一个程序/宏来使您的 Num Lock 始终保持打开状态,您需要首先测试以查看 NUM LOCK 是打开还是关闭,然后根据当前条件执行代码。

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

Public Function NumLock() As Boolean
    NumLock = KeyState(kNumlock)
    If (NumLock = True) Then
        MsgBox ("Num lock was off. Will turn back on now...")
        SendKeys "{NUMLOCK}", True
    Else: MsgBox ("Num Lock stayed on")
    End If
End Function

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


Sub myMainMethod()
    'do a function here that includes .SendKeys
    Call NumLock
End Sub

This sample program will give you a confirmation message as to whether the Num Lock is on or off, and turn it on if it is off.

这个示例程序会给你一个确认信息,确认数字锁定是打开还是关闭,如果它关闭,就打开它。

回答by user6772440

SendKeys "^{HOME}", Truewas turning off the num lockso I just repeated the command and it turns it back on again:

SendKeys "^{HOME}", True正在关闭,num lock所以我只是重复了这个命令,然后它又重新打开了:

SendKeys "^{HOME}", True
SendKeys "^{HOME}", True