在编辑单元格时按下键时是否有任何事件触发? [英] Is there any event that fires when keys are pressed when editing a cell?

查看:182
本文介绍了在编辑单元格时按下键时是否有任何事件触发?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否以任何方式将事件捕获为,您可以按工作表中的某个特定单元格进行编辑(编辑)



最近的一个是知道是更改事件,但只有在编辑的单元格被取消选择时才能被激活。我想捕获事件,而我正在编辑单元格。

解决方案

这是答案,我已经测试过了,它正在为我工​​作。



在Excel中跟踪键盘



有趣的问题:
MS Excel的 Worksheet_Change 事件将始终触发。陷入按键事件。使用excel标准或内置函数跟踪按键事件是不可能的。



这可以通过使用 API 来实现。

  Option Explicit 

私人类型POINTAPI
x As Long
y As Long
结束类型

私人类型MSG
hwnd As Long
消息长
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End键入

私有声明函数WaitMessage Libuser32()As Long

私有声明函数PeekMessage Libuser32别名PeekMessageA_
(ByRef lpMsg As MSG,ByVal hwnd As Long,_
ByVal wMsgFilterMin As Long,_
ByVal wMsgFilterMax As Long,_
ByVal wRemoveMsg As Long $ As

私有声明函数TranslateMessage Libuser32_
(ByRef lpMsg As MSG)As Long

私有声明函数PostMessage Libuser32别名PostMessageA_
(ByVal hwnd As Long,_
ByVal wMsg As Long,_
ByVal wParam As Long ,_
lParam As Any)As Long

私有声明函数FindWindow Libuser32别名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

Sub TrackKeyPressInit()

Dim msgMessage As MSG
Dim bCancel As Boolean
Dim iKeyCode As Integer
Dim lXLhwnd As Long

错误GoTo errHandler:
Application.EnableCancelKey = xlErrorHandler
'初始化此布尔标志。
bExitLoop = False
'获取应用程序hwnd。
lXLhwnd = FindWindow(XLMAIN,Application.Caption)
Do
WaitMessage
'检查按键,然后将其从msg队列中删除。
如果PeekMessage _
(msgMessage,lXLhwnd,WM_KEYDOWN,WM_KEYDOWN,PM_REMOVE)然后
'选择虚拟键代码供以后使用。
iKeyCode = msgMessage.wParam
'将虚拟键代码转换为char msg。
TranslateMessage msgMessage
PeekMessage msgMessage,lXLhwnd,WM_CHAR,_
WM_CHAR,PM_REMOVE
'为一些晦涩的原因,以下
'键未被捕获在事件处理程序内
'所以我们在这里处理它们。
如果iKeyCode = vbKeyBack然后SendKeys{BS}
如果iKeyCode = vbKeyReturn然后SendKeys{ENTER}
'假设cancel参数为False。
bCancel = False
'VBA RaiseEvent语句似乎没有返回ByRef参数
',所以我们调用一个KeyPress例程,而不是一个propper事件处理程序。
Sheet_KeyPress _
ByVal msgMessage.wParam,ByVal iKeyCode,ByVal Selection,bCancel
'如果按下的键被允许发布到应用程序。
如果bCancel = False然后
PostMessage _
lXLhwnd,msgMessage.Message,msgMessage.wParam,0
End If
End If
errHandler:
'允许处理其他msgs。
DoEvents
循环直到bExitLoop

End Sub

Sub StopKeyWatch()

'设置此布尔标志以退出上面的循环。
bExitLoop = True

End Sub


'\\这个例子说明了如何抓取工作表
'\\关键笔画,以防止在范围A1:D10中输入数字
'\\字符。
Private Sub Sheet_KeyPress(ByVal KeyAscii As Integer,_
ByVal KeyCode As Integer,_
ByVal Target As Range,_
Cancel As Boolean)

Const MSG As String = _
数字字符不允许在& _
vbNewLine& 范围:
Const TITLE As String =Invalid Entry!

如果不相交(目标,范围(A1:D10))没有,然后
如果Chr(KeyAscii)喜欢[0-9]然后
MsgBox MSG &安培;范围(A1:D10)。地址(False,False)_
& ,vbCritical,TITLE
取消= True
如果
结束如果

End Sub
/ pre>

Is it in any way possible to capture events as you press a key in (make an edit to) a specific cell in a worksheet?

The closest one is know is the Change Event but that can only be activated as soon the edited cell is deselected. I want to capture the event while I'm editing the cell.

解决方案

Here is the answer, I have tested the same and it is working properly for me.

Track the Keypress in Excel

Interesting Question: MS Excel's Worksheet_Change event always fired, when you are done with your changes and getting out of the cell. To trap the Key Press event. Tracking of Keypress event is not possible with excel standard or built-in functions.

This can be achieved by using the API.

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

Sub TrackKeyPressInit()

    Dim msgMessage As MSG
    Dim bCancel As Boolean
    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
        'check for a key press and remove it from the msg queue.
        If PeekMessage _
            (msgMessage, lXLhwnd, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE) Then
            'strore the virtual key code for later use.
            iKeyCode = msgMessage.wParam
           'translate the virtual key code into a char msg.
            TranslateMessage msgMessage
            PeekMessage msgMessage, lXLhwnd, WM_CHAR, _
            WM_CHAR, PM_REMOVE
           'for some obscure reason, the following
          'keys are not trapped inside the event handler
            'so we handle them here.
            If iKeyCode = vbKeyBack Then SendKeys "{BS}"
            If iKeyCode = vbKeyReturn Then SendKeys "{ENTER}"
           'assume the cancel argument is False.
            bCancel = False
            'the VBA RaiseEvent statement does not seem to return ByRef arguments
            'so we call a KeyPress routine rather than a propper event handler.
            Sheet_KeyPress _
            ByVal msgMessage.wParam, ByVal iKeyCode, ByVal Selection, bCancel
            'if the key pressed is allowed post it to the application.
            If bCancel = False Then
                PostMessage _
                lXLhwnd, msgMessage.Message, msgMessage.wParam, 0
            End If
        End If
errHandler:
        'allow the processing of other msgs.
        DoEvents
    Loop Until bExitLoop

End Sub

Sub StopKeyWatch()

    'set this boolean flag to exit the above loop.
    bExitLoop = True

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 Sheet_KeyPress(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

这篇关于在编辑单元格时按下键时是否有任何事件触发?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆