单击单元格时的操作

action when a cell is clicked

哼! 我是 VBA 的新手。 这可能是一个太简单的问题,但我正在努力使用 VBA: 当一个单元格(1,1)被点击时,因为它有 1,msgbox 会显示“hi”

Sub test()
  'click action 'when cell(1,1) is clicked and if cells(1,1) is 1, msgbox saying "hi" will show up, if not nothing If Cells(1, 1) = 1 Then
  MsgBox "hi"
  Else 
End If
End Sub

此代码属于工作sheet模块。

右键单击 sheet 选项卡并 select "View Code"

将此代码粘贴到此处:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Address = "$A" Then
        If Target = 1 Then
            MsgBox "hi"
        End If
    End If
End Sub

我面临的挑战是区分“通过光标移动在单元格上移动”和“通过鼠标单击的单元格”。 Worksheet_SelectionChange() 不会这样做。我找到了一些东西 here(也晚了,但也许仍然有价值)。

简而言之,在VBA编辑器中将以下代码添加到相关的sheet中:

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 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 Const PM_NOREMOVE = &H0
Private Const PM_QS_INPUT = &H20000

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
 
    Dim Message As MSG
 
    'check for left-mouse button clicks.
    PeekMessage Message, 0, 0, 0, PM_NOREMOVE Or PM_QS_INPUT
    'if left-mouse clicked on cell F4 run macro
    If Message.Message = 512 Then
        If Selection.Address = Range("f4").Address Then
            MsgBox "You clicked cell: " & Selection.Address
        End If
    End If
 
End Sub

工作原理:如果单元格发生变化(但是),则查询下一条有关鼠标移动的消息。如果它是 512 (WM_MOUSEMOVE) 并且位置与感兴趣的单元格匹配(在本例中为 F4),则显示消息框。


如果出现关于64位兼容性和使用PtrSafe的错误,可以输入以下内容(替换上面的定义):

Private Type MSG
    hwnd As LongLong
    Message As Long
    wParam As LongLong
    lParam As LongLong
    time As Long
    pt As POINTAPI
End Type

Private Declare PtrSafe Function PeekMessage Lib "user32" _
Alias "PeekMessageA" _
(ByRef lpMsg As MSG, ByVal hwnd As LongLong, _
ByVal wMsgFilterMin As Long, _
ByVal wMsgFilterMax As Long, _
ByVal wRemoveMsg As Long) As Long