【问题标题】:Double Click Event on Shapes形状上的双击事件
【发布时间】:2016-07-05 14:05:33
【问题描述】:

在我的研究中,我发现没有内置功能可以在 Excel 工作表上的形状上启用双击事件。我看到的许多解决方法都涉及编写类或其他类似的东西来添加此功能,所有这些似乎都超出了我的 VBA 知识库。因此,我编写了上面的代码(目前只是作为测试)来尝试为形状编写我自己的双击功能。

Public Clicked As Boolean, LastClickObj As String, LastClickTime As Date


Sub GenerateShapes()
    Dim sheet1 As Worksheet, shape As shape
    Set sheet1 = ThisWorkbook.Worksheets("Sheet1")
    Set shape = sheet1.Shapes.AddShape(msoShapeDiamond, 50, 50, 5, 5)
        shape.OnAction = "ShapeDoubleClick"
    Set shape = sheet1.Shapes.AddShape(msoShapeRectangle, 50, 60, 5, 5)
        shape.OnAction = "ShapeDoubleClick"
    LastClickTime = Now
End Sub


Sub ShapeDoubleClick()

    If Second(Now) - Second(LastClickTime) > 0.5 Then
        Clicked = False
        LastClickObj = ""
        LastClickTime = Now
    Else

        If Not Clicked Then
            Clicked = True
            LastClickObj = Application.Caller
        ElseIf LastClickObj = Application.Caller Then
            MsgBox ("Double Click")
            Clicked = False
            LastClickObj = ""
            LastClickTime = Now - 1
        Else
            LastClickObj = Application.Caller
            Clicked = True
            LastClickTime = Now
        End If
    End If


End Sub

但是,考虑到我合并计时器的方式,如果我快速连续单击 3 次,代码通常只会执行“双击”。我认为这与我如何处理Clicked 的超时“重置”有关,但逻辑可能存在其他问题。关于如何正确实现此功能的任何想法无需其他大量添加(如类等)?

【问题讨论】:

    标签: vba excel events shapes


    【解决方案1】:

    花了一些时间查看这个并通过一些调试意识到三次点击是由我点击的布尔值引起的。我在下面的解决方案完美地工作,包括形状区别,并且可以在代码中轻松调整点击延迟(我可以将其调整为其他地方的变量集,但现在硬编码功能就足够了)。在此处为希望将双击操作添加到其形状的未来用户发布我的解决方案

    Option Explicit
    
    Public LastClickObj As String, LastClickTime As Date
    
    Sub ShapeDoubleClick()
    
        If LastClickObj = "" Then
            LastClickObj = Application.Caller
            LastClickTime = CDbl(Timer)
        Else
            If CDbl(Timer) - LastClickTime > 0.25 Then
                LastClickObj = Application.Caller
                LastClickTime = CDbl(Timer)
            Else
                If LastClickObj = Application.Caller Then
                    MsgBox ("Double Click")
                    LastClickObj = ""
                Else
                    LastClickObj = Application.Caller
                    LastClickTime = CDbl(Timer)
                End If
            End If
        End If
    
    End Sub
    

    【讨论】:

    • 哈!我还认为单击是三次单击的问题-您找到了不错的解决方案。这是一个很好的谜题!
    • @DavidG 选择使用计时器,因为它需要从午夜开始的时间(以秒为单位)(因此,如果两次点击跨越午夜,则唯一可能发生的错误在这种用法中极不可能发生)
    【解决方案2】:

    编辑 3:我为此使用了没有跟踪单元的初始格式: 我认为它会将时间四舍五入,因此您必须使用我上面使用的语法才能使其在毫秒内工作。防止三次点击激活两次双击。

    Sub ShapeDoubleClick()
    
        Debug.Print Second(Now) - Second(LastClickTime)
    
        If Second(Now) - Second(LastClickTime) > 0.3 Then
            LastClickTime = Now
    
        ElseIf LastClickObj = Application.Caller And Clicked = False Then
    
                Debug.Print "Double Clicked!"
                Clicked = True
                LastClickTime = Now - 1
                LastClickObj = Application.Caller
                Exit Sub
    
        End If
    
        Clicked = False
        LastClickObj = Application.Caller
    End Sub
    

    【讨论】:

    • 意味着删除那个跟踪器单元(因为 msgbox 中断了宏,所以在我调试时就在那里)。这里的问题是这不需要在同一个对象上双击(这是必要的,因为最终实现将包含大量生成的形状)
    • 跟踪单元的轻松替换只是代表最后一次的另一个公共变量,所以这是一个简单的修复
    • 另外,如果现在只传入整秒值,我认为这将无法正常工作。你知道它是否包含几分之一秒吗?
    • 查看我的编辑。现在唯一的问题是当它超过 60 并且任何低于 1 秒的内容都可以作为双击。
    猜你喜欢
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 2019-08-05
    • 2011-05-19
    相关资源
    最近更新 更多