当编辑单元格时,是否有任何事件在按下键时触发?

12 浏览
0 Comments

当编辑单元格时,是否有任何事件在按下键时触发?

在工作表的特定单元格中按键(进行编辑)时,有没有任何可能捕获事件?最接近的方法是使用Change事件,但该事件只能在编辑单元格被取消选择后激活。我希望在编辑单元格时捕获事件。

0
0 Comments

有没有一种事件在编辑单元格时按键时触发?

我遇到了同样的问题,并通过在单元格上方放置一个文本框来解决它。我设置了文本框的属性,使其看起来像一个Excel单元格,然后使用相同的属性将其定位在单元格上方,并将宽度和高度设置为比单元格多一点。然后我将其设置为可见。我使用了KeyDown事件来处理按键。在我的代码中,我在单元格下方放置了一个列表框,用于显示另一个工作表上的匹配项列表。注意:此代码在工作表中,Cell变量在模块中声明为全局变量:Global Cell as Range。这比组合框要好得多。tb1是一个文本框,lb1是一个列表框。您将需要一个名为"Fruit"的工作表,其中包含第一列的数据。只有当所选单元格位于列=2并且为空时,此代码所在的工作表才会运行。不要忘记像上面提到的那样声明Cell。

Option Explicit
Private Sub lb1_Click()
  Cell.Value2 = lb1.Value
  tb1.Visible = False
  lb1.Visible = False
  Cell.Activate
End Sub
Private Sub tb1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Dim Row As Long
Dim Temp As String
  Select Case KeyCode
  Case vbKeyBack
    If Len(tb1.Value) > 0 Then tb1.Value = Left(tb1.Value, Len(tb1.Value) - 1)
  Case vbKeySpace, vbKeyA To vbKeyZ
    tb1.Value = WorksheetFunction.Proper(tb1.Value & Chr(KeyCode))
  Case vbKeyReturn
    If lb1.ListCount > 0 Then
      Cell.Value2 = lb1.List(0)
    Else
      Cell.Value2 = tb1.Value
      With Sheets("Fruit")
        .Cells(.UsedRange.Rows.Count + 1, 1) = tb1.Value
        .UsedRange.Sort Key1:=.Cells(1, 1), Header:=xlYes
      End With
      MsgBox tb1.Value & " has been added to the List"
    End If
    tb1.Visible = False
    lb1.Visible = False
    Cell.Activate
  Case vbKeyEscape
    tb1.Visible = False
    lb1.Visible = False
    Cell.Activate
  End Select
  lb1.Clear
  Temp = LCase(tb1.Value) & "*"
  With Sheets("Fruit")
    For Row = 2 To .UsedRange.Rows.Count
      If LCase(.Cells(Row, 1)) Like Temp Then
        lb1.AddItem .Cells(Row, 1)
      End If
    Next Row
  End With
KeyCode = 0
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  If Target.Column = 2 And Target.Cells.Count = 1 Then
    If Target.Value2 = Empty Then
      Set Cell = Target
      With Cell
        tb1.Top = .Top
        tb1.Left = .Left
        tb1.Height = .Height + 1
        tb1.Width = .Width + 1
      End With
      tb1.Value = Empty
      tb1.Visible = True
      tb1.Activate
      With Cell.Offset(1, 0)
        lb1.Top = .Top
        lb1.Left = .Left
        lb1.Width = .Width + 1
        lb1.Clear
        lb1.Visible = True
      End With
    Else
      tb1.Visible = False
      lb1.Visible = False
    End If
  Else
    tb1.Visible = False
    lb1.Visible = False
  End If
End Sub

如果还需要在模块中声明单元格变量和发送表单名称的代码,这将更有帮助。

0
0 Comments

有没有一个事件可以在编辑单元格时按键时触发?

这个问题的出现原因是,提供的答案对于处理Del、Backspace、Function Keys等按键的方式有一些限制,需要进行一些改进。解决方法是将原始消息发送回去,而不是翻译后的消息。还修改为使用带有事件的类模块,因为它在Excel 2010中可以正常工作,而且不需要将相同的代码复制到多个工作表中。

首先,创建一个名为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

然后,在工作表的代码模块中添加以下代码:

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

以上代码实现了在编辑单元格时按键触发事件的功能。

0
0 Comments

在编辑单元格时按下键盘时是否有任何事件触发?

这个问题的出现原因是,MS Excel的Worksheet_Change事件只在完成更改并退出单元格时触发。无法通过Excel的标准或内置函数来追踪按键事件。但可以通过使用API来实现。

解决方法如下:

1. 定义一个包含POINTAPI和MSG的数据类型。

2. 使用Declare关键字声明WaitMessage、PeekMessage、TranslateMessage、PostMessage和FindWindow函数。

3. 定义常量WM_KEYDOWN、PM_REMOVE和WM_CHAR。

4. 创建一个名为TrackKeyPressInit的子过程,使用Do循环来等待消息,并使用PeekMessage函数来检查是否有按键事件发生。如果有按键事件,则调用Sheet_KeyPress子过程处理按键事件,并根据需要取消按键事件。

5. 创建一个名为StopKeyWatch的子过程,用于退出Do循环。

6. 创建名为Sheet_KeyPress的事件处理程序,用于处理按键事件。在此示例中,它限制在"A1:D10"范围内输入数字字符,并在有违规输入时显示错误消息框。

需要注意的是,代码中使用了32位操作系统的函数声明和常量,如果使用64位操作系统,则需要使用PtrSafe版本的函数声明和常量。

此外,有用户提出了在Office 365中无法调用Sheet_KeyPress和TrackKeyPressInit的问题,可能是因为代码不适用于最新的Office版本。

至于如何返回在输入过程中输入到单元格中的字符数,暂时没有给出具体的解决方法。

,要在Excel中追踪按键事件,需要使用API函数和事件处理程序来实现。然而,代码的适用性可能会受到不同版本的Excel的影响。

0