vba用户窗体中由函数触发的倒计时

vba用户窗体中由函数触发的倒计时,vba,countdown,userform,Vba,Countdown,Userform,我想从运行的代码开始倒计时窗体。问题是如果我说 > TimerForm.Show 然后显示用户窗体,但不会触发倒计时。如何仅从用户窗体TimerLabel中显示倒计时的函数触发倒计时,如下所示 TimerForm.TimerLabel.Caption = Format(TimeSerial(0, 0, nTime), "hh:mm:ss") & " seconds " 然后,nTime将从30秒的初始值减少 下面的答案完全解决了这个问题。计时器的取消按钮应为 Priva

我想从运行的代码开始倒计时窗体。问题是如果我说

> TimerForm.Show
然后显示用户窗体,但不会触发倒计时。如何仅从用户窗体TimerLabel中显示倒计时的函数触发倒计时,如下所示

TimerForm.TimerLabel.Caption = Format(TimeSerial(0, 0, nTime), "hh:mm:ss") & " seconds "
然后,nTime将从30秒的初始值减少

下面的答案完全解决了这个问题。计时器的取消按钮应为

    Private Sub CancelTimer_Click()

Application.OnTime EarliestTime:=earliest, _
                       Procedure:=handler, _
                       schedule:=False
Unload Me
End
End Sub

如果没有,Application.OnTime将继续在后台运行。

不知道是否正确理解了问题,但以下是一些方法。嗯

标准模块代码

TimerForm类模块代码

有关OnTime的更多信息: ' http://www.cpearson.com/excel/ontime.aspx 选项显式 私有常量间隔为整数=1'秒 Private Const countdownInit为整数=30'秒 私有常量处理程序为String=“timerecursed” 二等兵 作为整数的私有倒计时 私有子用户表单_初始化() 倒计时=倒计时初始化 斯塔蒂默 端接头 专用子菜单取消\u单击() 计时器 卸下我 端接头 公共子StartTimer() 最早=现在+时间序列(0,0,间隔) Application.OnTime EarliesTime:=最早_ 过程:=处理程序_ 附表:=真 端接头 公共子停止计时器() 出错时继续下一步 倒计时=0 Application.OnTime EarliesTime:=最早_ 过程:=处理程序_ 附表:=假 端接头 公共Sub-OnTimeRecursed()
如果倒计时谢谢@dee-我真的不理解TimerForm代码中的“vbModeless”概念,我预览了一个带有“Private Sub CancelTimer_Click()”的取消按钮,内容应该很简单:“Unload Me End”。然而,如果我使用它,程序会有一个非常奇怪的行为——代码开始在userform代码和userform对象之间切换……因为我不确定什么对您很重要,所以我添加了这种“无模式”的可能性。无模式用户表单的要点是,可以在显示表单后调用某些用户表单公共函数。但是你可以忽略它,它可能不相关。好吧,忽略。VBA开发人员的滑稽行为无法控制。如果在计时器完成之前取消计时器,则无法停止闪烁。我假设它的Application.OnTime仍在运行。请查看编辑后的答案。取消按钮处理程序必须停止实时重新调度。如果在“取消”按钮事件处理程序中使用
End
,请不要使用它。更多信息请点击这里。基本上,
End
”立即终止执行。从来都不是自己需要的……”。
Option Explicit

Public Sub test()
    ' One possibility with modeless user form
    ' In this case it is possible to start timer after 
    ' timer form was displayed, because the form is modeless
    ' TimerForm.Show vbModeless
    ' TimerForm.StartTimer

    ' Other possiblity with modal user form
    ' In this case the StartTimer has to be called 
    ' from inside of user form because the form is modal.
    TimerForm.Show
End Sub

Public Sub TimerElapsed()
    TimerForm.OnTimerElapsed
End Sub
' More info about OnTime:
' http://www.cpearson.com/excel/ontime.aspx

Option Explicit

Private Const interval As Integer = 1 ' second
Private Const countdownInit As Integer = 30 ' seconds
Private Const handler As String = "TimerElapsed"
Private earliest As Double
Private countdown As Integer

Private Sub UserForm_Initialize()
    countdown = countdownInit
    StartTimer
End Sub

Private Sub Cancel_Click()
    StopTimer
    Unload Me
End Sub

Public Sub StartTimer()
    earliest = Now + TimeSerial(0, 0, interval)

    Application.OnTime EarliestTime:=earliest, _
                       Procedure:=handler, _
                       Schedule:=True
End Sub

Public Sub StopTimer()
    On Error Resume Next
    countdown = 0
    Application.OnTime EarliestTime:=earliest, _
                       Procedure:=handler, _
                       Schedule:=False
End Sub

Public Sub OnTimerElapsed()
    If countdown <= 0 Then
        Me.TimerLabel.Caption = "00:00:00 seconds "
        Exit Sub
    End If

    Dim timerInfo As String
    timerInfo = Format(TimeSerial(0, 0, countdown), "hh:mm:ss")
    Me.TimerLabel.Caption = timerInfo & " seconds "
    countdown = countdown - interval

    StartTimer ' <--- 'How can I trigger a countdown simply 
               ' from a function where the countdown is shown
               ' in the user form TimerLabel ...' 
               ' Here the OnTime is re-scheduled for next call.
End Sub