对于EXCEL工作表,我想触发 BeforeDoubleClick - 事件之前 SelectionChange - 事件
订单通常是反过来的: SelectionChange-event 首先,稍后 BeforeDoubleClick-event 。
我的目标是 运行MyDoubleClickCode,如果双击,或,如果没有,请运行 MyChangeSelectionCode
问题依赖于事件触发的顺序!
我的最佳解决方案来了:
' This Event is **MAYBE** fired secondly and runs the MyDoubleClickCode
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
dblFlag = true
...
MyDoubleClickCode
...
End Sub
' This event is always fired AND runs first
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
dblFlag = false
alertTime = Now + TimeValue("00:00:01")
Application.OnTime alertTime, "MyChangeSelectionSub"
End Sub
' Userdefined subroutine which will run one second after an event ( doubleclick or not).
public sub MyChangeSelectionSub()
If NOT dblFlag then
...
MyChangeSelectionCode
...
End if
End Sub
我在SelectionChange事件中使用 OnTime ,在触发选择更改后一秒钟调用MyChangeSelectionSub。这给了时间来处理BeforeDoubleClick事件并执行MyDoubleClickCode - 如果单元格也被双击。达到了我想要的逻辑,但是......
...它当然非常结实而且不令人满意:我必须在MyChangeSelectionSub启动之前等待一秒,而不是之后之前的AfterDoubleClick-event已被处理过。
也许有一种逻辑来实现这一目标?有什么想法吗?
编辑:我已经编辑了代码示例,以便更清楚地了解我的问题!我现在知道我不能改变事件的顺序,但是如何不使用onTime解决方案?
答案 0 :(得分:0)
这个对我来说“有效”,但似乎不稳定。 OnTime方法的计时可能会导致执行中我们可能需要接受的“不舒服的暂停”。 (或改进)。
'worksheet (Name) is "Sheet17" in the VBA Properties window
'worksheet Name is "Sheet1" as shown in the worksheet tab in the application Excel
Private double_click_detected As Boolean
Private SelectionChange_target As Range
' This Event is **MAYBE** fired secondly and runs the MyDoubleClickCode
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
double_click_detected = True
'...
MsgBox "MyDoubleClickCode"
'...
End Sub
' This event is always fired AND runs first
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Set SelectionChange_target = Target
alertTime = Now + TimeValue("00:00:01")
Application.OnTime alertTime, "Sheet17.MyChangeSelectionSub"
End Sub
' Userdefined subroutine which will run one second after an event ( doubleclick or not).
Public Sub MyChangeSelectionSub()
If Not double_click_detected Then
'...
MsgBox "MyChangeSelectionCode"
'...
End If
End Sub
答案 1 :(得分:0)
我找到了类似问题的解决方案,以避免在 https://www.herber.de/forum/archiv/1548to1552/1550413_Worksheet_BeforeRightClick.html(德语)上的 Worksheet_BeforeRightClick 事件之前避免 Worksheet_SelectionChange,并将其用于我的测试子。 您在 https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
上找到的完整虚拟键码列表Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)'just for sleep
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Const VK_LBUTTON = &H1 'Left mouse button
Const VK_RBUTTON = &H2 'Right mouse button
Const VK_SHIFT = &H10'Shiftkey just for fun to exit the sub
Sub TestGetAsyncKeyState()
Dim RMouseClick As Long, LMouseClick As Long
Dim RMouseClickpr As Long, LMouseClickpr As Long
Dim lShift As Long, iC As Integer
iC = 0
Do
DoEvents
lShift = GetAsyncKeyState(VK_SHIFT)
RMouseClickpr = RMouseClick
LMouseClickpr = LMouseClick
RMouseClick = GetAsyncKeyState(VK_RBUTTON)
LMouseClick = GetAsyncKeyState(VK_LBUTTON)
If RMouseClick <> RMouseClickpr Or LMouseClick <> LMouseClickpr Then Debug.Print vbLf; CStr(iC); ":"
If RMouseClick <> RMouseClickpr Then Debug.Print "Right: "; RMouseClick; "Previous: "; RMouseClickpr
If LMouseClick <> LMouseClickpr Then Debug.Print "Left : "; LMouseClick; "Previous: "; LMouseClickpr
' If RMouseClick <> RMouseClickpr Or LMouseClick <> LMouseClickpr Then Stop
Sleep (1000)
iC = iC + 1
If iC > 120 Then Stop '2
Loop While GetAsyncKeyState(VK_SHIFT) = 0 'End Loop by pressing any of the Shift-Keys
End Sub
它适用于鼠标点击 (1)、短时间按住鼠标按钮 (-32767) 和长时间按住鼠标按钮 (-32768)。不幸的是不是双击。
注意:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate 表示它检测到物理鼠标按钮。如果有人更改了设置,它将无法检测到正确的按钮。 MS 说你可以用 GetSystemMetrics(SM_SWAPBUTTON) 纠正这个问题。
希望有帮助。