使用 VBA 在 powerpoint 幻灯片中获取两次单击同一对象之间经过的时间

Get elapsed time between 2 clicks on the same object in power point slide using VBA

前提:我之前没用过VBA..

我想获得的东西: 直接在幻灯片内,当我点击一个形状或按钮时,我想启动计时器,当我再次点击 相同的 对象时,我想显示第一次之间经过的时间点击第二个..

这是我所做的:

我创建了一个表单并输入了以下代码

Private startTime As Date
Private endTime As Date


Private Sub CommandButton1_Click()
startTime = Now

End Sub

Private Sub CommandButton2_Click()
    endTime = Now


    TextBox2.Value = startTime
    TextBox3.Value = endTime
    TextBox1.Value = DateDiff("s", startTime, endTime)

End Sub

如您所见,我使用了 2 个按钮..我怎样才能只用 1 个按钮来做同样的事情?

是否可以不使用表格来做到这一点?

我觉得直接在slide里面会更漂亮(其实这也是我需要做的) 如果不是..我怎样才能使表格更漂亮?比如改变颜色、款式等等

你能给我什么建议吗?

试试这个小 mod 到你所拥有的:

Private Sub CommandButton1_Click()

Static StartTime As Double
Static Running As Boolean

Running = Not Running

If Running Then
    StartTime = Now
Else
    Running = False
    MsgBox DateDiff("s", StartTime, Now)
End If

End Sub

如果您先将 VBA 代码添加到您的演示文稿,然后再添加您将单击的特殊形状,则最容易理解。此处的代码位于常规模块中,将直接关联到您选择的任何幻灯片上的指定形状。

Option Explicit

Private alreadyStarted As Boolean

Public Sub ClickCatcher(ByRef actionShape As Shape)
    Debug.Print "shape clicked: " & actionShape.Name
    If Not alreadyStarted Then
        StartCounter
        alreadyStarted = True
    Else
        Dim elapsed As Double
        elapsed = TimeElapsed() / 1000#
        MsgBox "Time Elapsed: " & Format(elapsed, "#.000 sec")
        alreadyStarted = False
    End If
End Sub

(我将在下面向您展示计时器代码)

很容易看出,使用全局变量alreadyStarted,您可以切换定时器的启动和停止,并报告经过的时间(以毫秒为单位)。

Debug.Print 语句显示被单击的形状的名称。如果您有多个动作形状,这个 可能 很重要。因此,您或许可以检查计时器形状的名称,而不是其他形状。

您需要的最后设置是向您 select 编辑的幻灯片添加 "action shape"。您可以从 INSERT 功能区执行此操作,然后是 select Shapes 并一直滚动到底部,直到看到 Action Shapes . Select 你喜欢的任何一个都可以添加到幻灯片中。您会立即看到一个弹出对话框,要求您进行操作设置。确保你 select 运行 宏 并且你的例程的名称是 selected(在这种情况下为 ClickCatcher)。

现在进入演示模式并在该形状上单击一次,然后再次单击,MsgBox 将弹出显示经过的时间。

这是精确计时器代码。我建议创建一个单独的代码模块并将此代码复制到那里。

Option Explicit

'------------------------------------------------------------------------------
' For Precision Counter methods
'
Private Type LargeInteger
    lowpart As Long
    highpart As Long
End Type

Private Declare Function QueryPerformanceCounter Lib _
                         "kernel32" (lpPerformanceCount As LargeInteger) As Long
Private Declare Function QueryPerformanceFrequency Lib _
                         "kernel32" (lpFrequency As LargeInteger) As Long

Private counterStart As LargeInteger
Private counterEnd As LargeInteger
Private crFrequency As Double

Private Const TWO_32 = 4294967296#               ' = 256# * 256# * 256# * 256#

'==============================================================================
' Precision Timer Controls
'
Private Function LI2Double(lgInt As LargeInteger) As Double
    '--- converts LARGE_INTEGER to Double
    Dim low As Double
    low = lgInt.lowpart
    If low < 0 Then
        low = low + TWO_32
    End If
    LI2Double = lgInt.highpart * TWO_32 + low
End Function

Public Sub StartCounter()
    '--- Captures the high precision counter value to use as a starting
    '    reference time.
    Dim perfFrequency As LargeInteger
    QueryPerformanceFrequency perfFrequency
    crFrequency = LI2Double(perfFrequency)
    QueryPerformanceCounter counterStart
End Sub

Public Function TimeElapsed() As Double
    '--- Returns the time elapsed since the call to StartCounter in microseconds
    If crFrequency = 0# Then
        Err.Raise Number:=11, _
                  Description:="Must call 'StartCounter' in order to avoid " & _
                                "divide by zero errors."
    End If
    Dim crStart As Double
    Dim crStop As Double
    QueryPerformanceCounter counterEnd
    crStart = LI2Double(counterStart)
    crStop = LI2Double(counterEnd)
    TimeElapsed = 1000# * (crStop - crStart) / crFrequency
End Function