Introduction | Example | Tutorial | Applications
Introduction - GetAsyncKeyState VBA
This tutorial shows you how to pause your macro until a key is pressed by calling the GetAsyncKeyState function in VBA. By doing this, you’re able to detect key strokes so you can trigger an action when a key is pressed.
I know this doesn’t literally pause your macro while you wait for a key to be pressed, but in essence that’s the functionality you’re recreating. You can use this feature to exit a userform when a key is pressed or to control the logic of your macro using key presses.
Example - GetAsyncKeyState VBA
Display a message when the F9 key is pressed
#If VBA7 Then 'declare virtual key event listener Private Declare PtrSafe Function GetAsyncKeyState Lib "user32" _ (ByVal vKey As Long) As Integer #Else 'declare virtual key event listener Private Declare Function GetAsyncKeyState Lib "user32" _ (ByVal vKey As Long) As Integer #End If Private Const VK_F9 = &H78 Sub WaitUntilF9Key() Do Until GetAsyncKeyState(VK_F9) DoEvents Loop MsgBox "Hello World" End Sub
Make powerful macros with our free VBA Developer's Kit
There's a lot to unpack here. To save time and become really good at VBA, make sure you get our free VBA Developer's Kit below. It's full of shortcuts, tips and pre-built macros to make writing VBA easier.
Tutorial - GetAsyncKeyState VBA
There you have it. This macro stays in a loop until the user presses F9. The F9 key is a virtual key constant I declared using the hexadecimal value 78. For a full list of the virtual key constants in VBA format, jump here.
Because the DoEvents method is invoked, the user is able to contine doing whatever he/she wants in Excel. The user can enter data, change data, switch applications and more - just like they normally would. But, the moment they hit the F9 key, the loop ends and the user is presented with a message box.
This is exactly what I do on the Recording screen of my Mouse To Macro Excel Add-in.
If you’re trying to figure out what all the junk about VBA7 at the top of the macro is, it’s just so the macro will work on both 32-bit and 64-bit machines. When you see someone use the PtrSafe keyword in VBA like I did up there, that’s usually what he/she is trying to do.
But I digress. You can make more complicated codes than this. For example, why do you have to leave the loop when a key is pressed? Can you present different information when different keys are pressed?
You better believe you can! Take a look.
More Advanced Example - GetAsyncKeyState VBA
Open notepad or speak the time, depending on which key is pressed
#If VBA7 Then 'declare virtual key event listener Private Declare PtrSafe Function GetAsyncKeyState Lib "user32" _ (ByVal vKey As Long) As Integer #Else 'declare virtual key event listener Private Declare Function GetAsyncKeyState Lib "user32" _ (ByVal vKey As Long) As Integer #End If Private Const VK_F9 = &H78 Private Const VK_F10 = &H79 Private Const VK_0 = &H30 Sub WaitUntilKey() Do Until GetAsyncKeyState(VK_F9) 'exit when F9 key is pressed DoEvents If GetAsyncKeyState(VK_F10) Then 'if F10 key is pressed 'open notepad Call Shell("Explorer.exe ""C:\Windows\system32\notepad.exe""", vbNormalFocus) ElseIf GetAsyncKeyState(VK_0) Then 'if 0 key is pressed 'Speak the time Application.Speech.Speak "The time is " & Time, True, , True End If Loop End Sub
You can run this macro in the background and anytime you press the F10 key, a new notepad will open.
Likewise, if you run this macro from Excel, anytime you press the 0 key, your computer will speak and tell you what time it is.
Like before, once you hit the F9 key, the macro will end.
I gotta admit. Capturing keystrokes still makes me giddy when I see it in a macro. It’s just so flipping neat!
Full List of GetAsyncKeyState Virtual Keys
I’m sure you noticed I only declared the keys I was looking for in the previous example. That’s only because I’m lazy.
I’m going to make this easy for you by defining EVERY virtual key, including mouse clicks, you can detect with the GetAsyncKeyState function. Even better, I’m going to do it in VBA format so you can copy and paste it in your own macro. By copying and pasting this into the top of your own macro, you’ll be able to run different branches of your macro logic when different keys are pressed.
This is incredibly powerful. Without further delay, here’s the VBA code:
Virtual Keys in VBA Format
#If VBA7 Then Private Declare PtrSafe Function GetAsyncKeyState Lib "user32" _ (ByVal vKey As Long) As Integer #Else Private Declare Function GetAsyncKeyState Lib "user32" _ (ByVal vKey As Long) As Integer #End If 'List compiled by Ryan Wells at wellsr.com Private Const VK_LBUTTON = &H1 'Left mouse button Private Const VK_RBUTTON = &H2 'Right mouse button Private Const VK_CANCEL = &H3 'Control-break processing Private Const VK_MBUTTON = &H4 'Middle mouse button (three-button mouse) Private Const VK_BACK = &H8 'BACKSPACE key Private Const VK_TAB = &H9 'TAB key Private Const VK_CLEAR = &HC 'CLEAR key Private Const VK_RETURN = &HD 'ENTER key Private Const VK_SHIFT = &H10 'SHIFT key Private Const VK_CONTROL = &H11 'CTRL key Private Const VK_MENU = &H12 'ALT key Private Const VK_PAUSE = &H13 'PAUSE key Private Const VK_CAPITAL = &H14 'CAPS LOCK key Private Const VK_ESCAPE = &H1B 'ESC key Private Const VK_SPACE = &H20 'SPACEBAR Private Const VK_PRIOR = &H21 'PAGE UP key Private Const VK_NEXT = &H22 'PAGE DOWN key Private Const VK_END = &H23 'END key Private Const VK_HOME = &H24 'HOME key Private Const VK_LEFT = &H25 'LEFT ARROW key Private Const VK_UP = &H26 'UP ARROW key Private Const VK_RIGHT = &H27 'RIGHT ARROW key Private Const VK_DOWN = &H28 'DOWN ARROW key Private Const VK_SELECT = &H29 'SELECT key Private Const VK_PRINT = &H2A 'PRINT key Private Const VK_EXECUTE = &H2B 'EXECUTE key Private Const VK_SNAPSHOT = &H2C 'PRINT SCREEN key Private Const VK_INSERT = &H2D 'INS key Private Const VK_DELETE = &H2E 'DEL key Private Const VK_HELP = &H2F 'HELP key Private Const VK_0 = &H30 '0 key Private Const VK_1 = &H31 '1 key Private Const VK_2 = &H32 '2 key Private Const VK_3 = &H33 '3 key Private Const VK_4 = &H34 '4 key Private Const VK_5 = &H35 '5 key Private Const VK_6 = &H36 '6 key Private Const VK_7 = &H37 '7 key Private Const VK_8 = &H38 '8 key Private Const VK_9 = &H39 '9 key Private Const VK_A = &H41 'A key Private Const VK_B = &H42 'B key Private Const VK_C = &H43 'C key Private Const VK_D = &H44 'D key Private Const VK_E = &H45 'E key Private Const VK_F = &H46 'F key Private Const VK_G = &H47 'G key Private Const VK_H = &H48 'H key Private Const VK_I = &H49 'I key Private Const VK_J = &H4A 'J key Private Const VK_K = &H4B 'K key Private Const VK_L = &H4C 'L key Private Const VK_M = &H4D 'M key Private Const VK_N = &H4E 'N key Private Const VK_O = &H4F 'O key Private Const VK_P = &H50 'P key Private Const VK_Q = &H51 'Q key Private Const VK_R = &H52 'R key Private Const VK_S = &H53 'S key Private Const VK_T = &H54 'T key Private Const VK_U = &H55 'U key Private Const VK_V = &H56 'V key Private Const VK_W = &H57 'W key Private Const VK_X = &H58 'X key Private Const VK_Y = &H59 'Y key Private Const VK_Z = &H5A 'Z key Private Const VK_NUMPAD0 = &H60 'Numeric keypad 0 key Private Const VK_NUMPAD1 = &H61 'Numeric keypad 1 key Private Const VK_NUMPAD2 = &H62 'Numeric keypad 2 key Private Const VK_NUMPAD3 = &H63 'Numeric keypad 3 key Private Const VK_NUMPAD4 = &H64 'Numeric keypad 4 key Private Const VK_NUMPAD5 = &H65 'Numeric keypad 5 key Private Const VK_NUMPAD6 = &H66 'Numeric keypad 6 key Private Const VK_NUMPAD7 = &H67 'Numeric keypad 7 key Private Const VK_NUMPAD8 = &H68 'Numeric keypad 8 key Private Const VK_NUMPAD9 = &H69 'Numeric keypad 9 key Private Const VK_SEPARATOR = &H6C 'Separator key Private Const VK_SUBTRACT = &H6D 'Subtract key Private Const VK_DECIMAL = &H6E 'Decimal key Private Const VK_DIVIDE = &H6F 'Divide key Private Const VK_F1 = &H70 'F1 key Private Const VK_F2 = &H71 'F2 key Private Const VK_F3 = &H72 'F3 key Private Const VK_F4 = &H73 'F4 key Private Const VK_F5 = &H74 'F5 key Private Const VK_F6 = &H75 'F6 key Private Const VK_F7 = &H76 'F7 key Private Const VK_F8 = &H77 'F8 key Private Const VK_F9 = &H78 'F9 key Private Const VK_F10 = &H79 'F10 key Private Const VK_F11 = &H7A 'F11 key Private Const VK_F12 = &H7B 'F12 key Private Const VK_F13 = &H7C 'F13 key Private Const VK_F14 = &H7D 'F14 key Private Const VK_F15 = &H7E 'F15 key Private Const VK_F16 = &H7F 'F16 key Private Const VK_NUMLOCK = &H90 'NUM LOCK key Private Const VK_SCROLL = &H91 'SCROLL LOCK key Private Const VK_LSHIFT = &HA0 'Left SHIFT key Private Const VK_RSHIFT = &HA1 'Right SHIFT key Private Const VK_LCONTROL = &HA2 'Left CONTROL key Private Const VK_RCONTROL = &HA3 'Right CONTROL key Private Const VK_LMENU = &HA4 'Left MENU key Private Const VK_RMENU = &HA5 'Right MENU key Private Const VK_PLAY = &HFA 'Play key Private Const VK_ZOOM = &HFB 'Zoom key 'REMINDER: To remind yourself how to use these keys ' with the GetAsyncKeyState function, please visit: ' http://wellsr.com/vba/2017/excel/GetAsyncKeyState-vba-to-wait-until-a-key-is-pressed/
I haven’t tested every one of these keystrokes, so if you find any errors, please leave a comment and let me know. I’ll work to improve the list with your feedback.
Application Ideas - GetAsyncKeyState VBA
I can see your wheels turning already! Having all these key detection tools at your disposal gives you an incredible amount of power. I’m excited to hear what kind of VBA applications you plan on making with this.
Like I said, I use this in my Mouse To Macro add-in to begin recording and to unload a userform when a certain key is pressed. But that’s just one of an infinite number of possibilities you can do. Leave me a comment with what you’d like to see done with the GetAsyncKeyState function!
Now’s the time I
beg ask you to subscribe to my free wellsrPRO VBA Training Program. Once you subscribe, you’ll get access to a free copy of my Excel Add-In with tons of useful features and you’ll get email tutorials where I show you how to do some pretty cool stuff with VBA:)