I know this is an old question, but I recently needed similar functionality and the provided answer had some limitations that I had to address with how it handled (or didn’t handle) the Del, Backspace, Function Keys, etc.
The fix is to post back back the original message instead of the translated one.
Also changed to use a Class Module with Events since it works fine in Excel 2010 and I didn’t want to copy the same code to multiple sheets:
Class Module (Name it KeyPressApi)
Option Explicit
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type MSG
hwnd As Long
Message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type
Private Declare Function WaitMessage Lib "user32" () As Long
Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" _
(ByRef lpMsg As MSG, ByVal hwnd As Long, _
ByVal wMsgFilterMin As Long, _
ByVal wMsgFilterMax As Long, _
ByVal wRemoveMsg As Long) As Long
Private Declare Function TranslateMessage Lib "user32" _
(ByRef lpMsg As MSG) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Const WM_KEYDOWN As Long = &H100
Private Const PM_REMOVE As Long = &H1
Private Const WM_CHAR As Long = &H102
Private bExitLoop As Boolean
Public Event KeyPressed
(ByVal KeyAscii As Integer, _
ByVal KeyCode As Integer, _
ByVal Target As Range, _
ByRef Cancel As Boolean)
Public Sub StartKeyPressInit()
Dim msgMessage As MSG
Dim bCancel As Boolean
Dim iMessage As Integer
Dim iKeyCode As Integer
Dim lXLhwnd As Long
On Error GoTo errHandler
Application.EnableCancelKey = xlErrorHandler
'Initialize this boolean flag.
bExitLoop = False
'Get the app hwnd.
lXLhwnd = FindWindow("XLMAIN", Application.Caption)
Do
WaitMessage
'Exit the loop if we were aborted
If bExitLoop Then Exit Do
'Check for a key press and remove it from the msg queue.
If PeekMessage(msgMessage, lXLhwnd, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE) Then
'Store the virtual key code for later use.
iMessage = msgMessage.Message
iKeyCode = msgMessage.wParam
'Translate the virtual key code into a char msg.
TranslateMessage msgMessage
PeekMessage msgMessage, lXLhwnd, WM_CHAR, WM_CHAR, PM_REMOVE
bCancel = False
RaiseEvent KeyPressed(msgMessage.wParam, iKeyCode, Selection, bCancel)
'If not handled, post back to the window using the original values
If Not bCancel Then
PostMessage lXLhwnd, iMessage, iKeyCode, 0
End If
End If
errHandler:
'Allow the processing of other msgs.
DoEvents
Loop Until bExitLoop
End Sub
Public Sub StopKeyPressWatch()
'Set this boolean flag to exit the above loop.
bExitLoop = True
End Sub
Usage
Option Explicit
Dim WithEvents CKeyWatcher As KeyPressApi
Private Sub Worksheet_Activate()
If CKeyWatcher Is Nothing Then
Set CKeyWatcher = New KeyPressApi
End If
CKeyWatcher.StartKeyPressInit
End Sub
Private Sub Worksheet_Deactivate()
CKeyWatcher.StopKeyPressWatch
End Sub
'\This example illustrates how to catch worksheet
'\Key strokes in order to prevent entering numeric
'\characters in the Range "A1:D10" .
Private Sub CKeyWatcher_KeyPressed(ByVal KeyAscii As Integer, _
ByVal KeyCode As Integer, _
ByVal Target As Range, _
Cancel As Boolean)
Const MSG As String = _
"Numeric Characters are not allowed in" & _
vbNewLine & "the Range: """
Const TITLE As String = "Invalid Entry !"
If Not Intersect(Target, Range("A1:D10")) Is Nothing Then
If Chr(KeyAscii) Like "[0-9]" Then
MsgBox MSG & Range("A1:D10").Address(False, False) _
& """ .", vbCritical, TITLE
Cancel = True
End If
End If
End Sub
- Remove From My Forums
-
Question
-
Hi,
I would like to know how to handle keyboard events in Excel VBA forms. I would like to capture the KeyPress, KeyDown or KeyUp events when a Excel VBA form has focus.
Thanks
Kaizenn
.
All replies
-
The form controls have events to which you can attach event handling procs. If you right click the control and select to see its properties, there should be an events tab at the properties pane. Just press the «…» button next to the event you wish to handle to make such a proc
-
Hi George…thanks for the post..but here I am not talking abt events associated to controls on the form. I just want to respond to some keys which are not directly associated to any control on the form..i.e when the form is active. From what I have read on the net so far it seems to be a bit tricky and looks like there is no easy way out. I would be grateful if I can get some help.
Thanks
Kaizenn.
-
Just to bring the topic to notice again….Can someone help me out?
-
Hey,
Maybe this is in conformity with what you are looking for…
Code Snippet
Private Sub UserForm_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
MsgBox Chr(KeyAscii)
End Sub
Best Regards
Cathrine
-
I suppose you want to «preview» keypresses at the form, even though other control has the focus. This is possible (if I remember well it’s a form property called KeyPreview or something like that you have to set to true). Checkout how I implement F1/F2/etc. hotkey support at LVS application (http://www.codeplex.com/lvs)
-
Hey,
There is no KeyPreview property in Excel VBA.
Cath
-
Oops, sorry, didn’t notice the forum was on VBA (I was checking the «unanswered» questions forum). You can still define HotKeys somehow I think, you may need to add some hidden button on the form and set a shortcut key to it. What exactly do you want to do (which keys to grab? can you describe the scenario?)
-
Thanks for the posts.
Cathrine..the Form_keypress doesnt work at all and that is the very reason I was caught up here. The hidden button seems to be one solution, which I didnt want to try out as I thought there might be something better..I dont know how to get that form keypress event to work. It just never executes
-
You were asking to capture the KeyPress events when an Excel VBA form has the focus. Well, the form can only have focus if it has no controls, so… if you have controls on your form set the controls visible or enabled property to false… and the code snippet will execute.
Cath
acShiftMask Битовая маска для клавиши SHIFT.
acCtrlMask Битовая маска для клавиши CTRL.
acAltMask Битовая маска для клавиши ALT.
Замечания
Событие KeyDown применяется только к формам и элементам управления в форме, а не к элементам управления в отчете.
Чтобы выполнить макрос или процедуру события при возникновении этих событий, задайте для свойства OnKeyDown имя макроса или [Процедура события].
Для обоих событий объект с фокусом получает все нажатия клавиши. Форма может быть в фокусе, только если на ней нет элементов управления или все ее видимые элементы управления недоступны.
Форма также будет получать все события клавиатуры, даже те, которые происходят для элементов управления, если для свойства KeyPreview формы задано значение Да. При этом параметре свойства все события клавиатуры происходят сначала для формы, а затем для элемента управления, на который установлен фокус. Вы можете отвечать на определенные клавиши, нажатые в форме, независимо от того, какой элемент управления имеет фокус. Например, может потребоваться, чтобы сочетание клавиш CTRL+X всегда выполняло одно и то же действие в форме.
Если вы нажимаете и удерживаете клавишу, события KeyDown и KeyPress чередуются несколько раз (KeyDown, KeyPress, KeyDown, KeyPress и т. д.), пока вы не отпустите ключ, а затем произойдет событие KeyUp.
Хотя событие KeyDown возникает при нажатии большинства клавиш, оно обычно используется для распознавания или различия между:
Расширенные клавиши знаков, такие как функциональные клавиши.
Клавиши навигации, такие как Главная, Конец, PgUp, PgDn, СТРЕЛКА ВВЕРХ, СТРЕЛКА ВНИЗ, СТРЕЛКА ВПРАВО, СТРЕЛКА ВЛЕВО и TAB.
Сочетания клавиш и стандартных модификаторов клавиатуры (клавиши SHIFT, CTRL или ALT).
Клавиши цифр числовой панели и клавиатуры.
Событие KeyDown не возникает при нажатии:
Клавиша ВВОД, если в форме есть кнопка команды, для которой свойство По умолчанию имеет значение Да.
Клавиша ESC, если форма содержит кнопку команды, для которой свойство Cancel имеет значение Да.
Событие KeyDown возникает при нажатии или отправке клавиши ANSI. Событие KeyUp возникает после любого события для элемента управления, вызванного нажатием или отправкой клавиши. Если нажатие клавиши приводит к переходу фокуса с одного элемента управления на другой, для первого элемента управления возникает событие KeyDown , а для второго — события KeyPress и KeyUp .
Чтобы узнать символ ANSI, соответствующий нажатой клавише, используйте событие KeyPress .
Если модальное диалоговое окно отображается в результате нажатия или отправки клавиши, происходят события KeyDown и KeyPress , но событие KeyUp не возникает.
Пример
В следующем примере определяется, нажата ли клавиша SHIFT, CTRL или ALT.
Чтобы попробовать пример, добавьте следующую процедуру события в форму, содержащую текстовое поле с именем KeyHandler.
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
KeyDown, KeyUp events
Occur in sequence when a user presses and releases a key. KeyDown occurs when the user presses a key. KeyUp occurs when the user releases a key.
Syntax
Private Subobject _KeyDown( ByValKeyCodeAs MSForms.ReturnInteger, ByValShiftAs fmShiftState)
Private Subobject _KeyUp( ByValKeyCodeAs MSForms.ReturnInteger, ByValShiftAs fmShiftState)
The KeyDown and KeyUp event syntaxes have these parts:
Part | Description |
---|---|
object | Required. A valid object name. |
KeyCode | Required. An integer that represents the key code of the key that was pressed or released. |
Shift | Required. The state of SHIFT, CTRL, and ALT. |
Settings
The settings for Shift are:
Constant | Value | Description |
---|---|---|
fmShiftMask | 1 | SHIFT was pressed. |
fmCtrlMask | 2 | CTRL was pressed. |
fmAltMask | 4 | ALT was pressed. |
Remarks
The KeyDown event occurs when the user presses a key on a running form while that form or a control on it has the focus. The KeyDown and KeyPress events alternate repeatedly until the user releases the key, at which time the KeyUp event occurs. The form or control with the focus receives all keystrokes. A form can have the focus only if it has no controls or all its visible controls are disabled.
These events also occur if you send a keystroke to a form or control by using either the SendKeys action in a macro or the SendKeys statement in Visual Basic.
The KeyDown and KeyUp events are typically used to recognize or distinguish between:
Extended character keys, such as function keys.
Navigation keys, such as HOME, END, PAGEUP, PAGEDOWN, UP ARROW, DOWN ARROW, RIGHT ARROW, LEFT ARROW, and TAB.
Combinations of keys and standard keyboard modifiers (SHIFT, CTRL, or ALT).
The numeric keypad and keyboard number keys.
The KeyDown and KeyUp events don’t occur under the following circumstances:
The user presses Enter on a form with a command button whose Default property is set to True.
The user presses Esc on a form with a command button whose Cancel property is set to True.
The KeyDown and KeyPress events occur when you press or send an ANSI key. The KeyUp event occurs after any event for a control caused by pressing or sending the key. If a keystroke causes the focus to move from one control to another control, the KeyDown event occurs for the first control, while the KeyPress and KeyUp events occur for the second control.
The sequence of keyboard-related events is:
The KeyDown and KeyUp events apply only to forms and controls on a form. To interpret ANSI characters or to find out the ANSI character corresponding to the key pressed, use the KeyPress event.
See also
Support and feedback
Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.
Источник
Событие TextBox.KeyUp (Access)
Событие KeyUp возникает, когда пользователь отпускает ключ, когда форма или элемент управления имеет фокус. Это событие также возникает при отправке нажатия клавиши в форму или элемент управления с помощью действия SendKeys в макросе или инструкции SendKeys в Visual Basic.
Синтаксис
expression. KeyUp (KeyCode, SHIFT)
Выражение Переменная, представляющая объект TextBox .
Параметры
Имя | Обязательный или необязательный | Тип данных | Описание |
---|---|---|---|
KeyCode | Обязательный | Integer | Код ключа, например vbKeyF1 (клавиша F1) или vbKeyHome (ключ home). Чтобы указать коды ключей, используйте встроенные константы, показанные в обозревателе объектов. Вы можете запретить объекту получать нажатие клавиши, задав для keyCode значение 0. |
Shift | Обязательный | Integer | Состояние клавиш SHIFT, CTRL и ALT во время события. Если необходимо протестировать аргумент Shift , можно использовать одну из следующих встроенных констант в качестве битовых масок:
acShiftMask Битовая маска для клавиши SHIFT. acCtrlMask Битовая маска для клавиши CTRL. acAltMask Битовая маска для клавиши ALT. ЗамечанияЧтобы выполнить макрос или процедуру события при возникновении этих событий, задайте для свойства OnKeyUp имя макроса или [Процедура события]. Для обоих событий объект с фокусом получает все нажатия клавиши. Форма может быть в фокусе, только если на ней нет элементов управления или все ее видимые элементы управления недоступны. Форма также будет получать все события клавиатуры, даже те, которые происходят для элементов управления, если для свойства KeyPreview формы задано значение Да. При этом параметре свойства все события клавиатуры происходят сначала для формы, а затем для элемента управления, на который установлен фокус. Вы можете отвечать на определенные клавиши, нажатые в форме, независимо от того, какой элемент управления имеет фокус. Например, может потребоваться, чтобы сочетание клавиш CTRL+X всегда выполняло одно и то же действие в форме. Если вы нажимаете и удерживаете клавишу, события KeyDown и KeyPress чередуются несколько раз (KeyDown, KeyPress, KeyDown, KeyPress и т. д.), пока вы не отпустите ключ, и произойдет событие KeyUp . Хотя событие KeyUp возникает при нажатии большинства клавиш, оно обычно используется для распознавания или различия между: Расширенные клавиши знаков, такие как функциональные клавиши. Клавиши навигации, такие как Главная, Конец, PgUp, PgDn, СТРЕЛКА ВВЕРХ, СТРЕЛКА ВНИЗ, СТРЕЛКА ВПРАВО, СТРЕЛКА ВЛЕВО и TAB. Сочетания клавиш и стандартных модификаторов клавиатуры (клавиши SHIFT, CTRL или ALT). Клавиши цифр числовой панели и клавиатуры. Событие KeyUp не возникает при нажатии: Клавиша ВВОД, если в форме есть кнопка команды, для которой свойство По умолчанию имеет значение Да. Клавиша ESC, если форма содержит кнопку команды, для которой свойство Cancel имеет значение Да. Событие KeyUp возникает после любого события для элемента управления, вызванного нажатием или отправкой клавиши. Если нажатие клавиши приводит к переходу фокуса с одного элемента управления на другой, для первого элемента управления возникает событие KeyDown , а для второго — события KeyPress и KeyUp . Чтобы узнать символ ANSI, соответствующий нажатой клавише, используйте событие KeyPress . Если модальное диалоговое окно отображается в результате нажатия или отправки клавиши, происходят события KeyDown и KeyPress , но событие KeyUp не возникает. Поддержка и обратная связьЕсть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь. Источник Читайте также: Как настроить аутлук для почты майл ру Adblock |
События:
KeyDown KeyUp KeyPress
Посылаются форме когда производится ввод данных. Событие KeyPress возникает когда пользователь нажимает клавишу, у которой есть ASCII код. Это событие не сгенирируется при нажатии функциональных клавиш. При том эти события есть как у формы:
Private Sub UserForm_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) End Sub
Так и у элементов управления TextBox, например:
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) End Sub
А это в свою очередь позволяет проверять ввод. Например, если в поле нужно ввести цифру, то легко проверить, что вводит пользователь. События KeyUp и KeyDown применяются для специальных функциональных клавиш или комбинаций типа Ctrl+Del, так как событие KeyPress их не отловит. Удобно использовать данное событие для проверки заполненности полей. Вот форма:
А вот код для нее. В момент нажатия ввода символа в поле проверяется заполненость полей:
Private Sub Test() Dim ctrl As Control Dim bool As Boolean bool = True For Each ctrl In Controls If TypeName(ctrl) = "TextBox" Then If ctrl.Text = "" Then bool = False End If End If Next ctrl UserForm1.CommandButton1.Enabled = bool End Sub Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) Call Test End Sub Private Sub TextBox2_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) Call Test End Sub Private Sub TextBox3_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) Call Test End Sub
|
|