首页 > 解决方案 > 如何在用户窗体文本框中设置计时器?

问题描述

我有一个完美运行的代码,但我必须单击命令按钮才能激活它。

我想要的是当我打开工作簿/用户窗体时计时器自动运行。

当计时器达到 0 秒时,我希望工作簿使用自动关闭

Workbooks("OUTIL_CRN.xlsm").Save
Workbooks("OUTIL_CRN.xlsm").Close

这是与命令按钮一起使用的代码:

在一个模块中:

Public Const AllowedTime As Double = 1

在用户窗体中:

Private Sub CommandButton1_Click()

Dim userClickedPause As Boolean ' Gets set to True by the Pause button

Dim stopTime As Date

    userClickedPause = False
    ' If AllowedTime is the number of minutes with a decimal part:
    stopTime = DateAdd("s", Int(AllowedTime * 600), Now) ' add seconds to current time

    ' If AllowedTime is the number of seconds:
    'stopTime = DateAdd("s", AllowedTime, Now) ' add seconds to current time
    Do
        With UserForm1.TextBox1
            .Value = Format(stopTime - Now, "Nn:Ss")
        End With
        DoEvents
        If userClickedPause = True Then
            Exit Do
        End If
    Loop Until Now >= stopTime


End Sub
Private Sub CommandButton2_Click()
    userClickedPause = True
End Sub

标签: excelvba

解决方案


很大程度上取决于您如何显示表格。如果你有这个:

UserForm1.Show

然后表单是模态的,显示默认实例,您可以Activate在对话框激活时处理事件以执行代码。

如果你有这个:

UserForm1.Show vbModeless

然后表单不是模态的,并且该Activate事件将是一个问题,因为每当用户通过单击屏幕上的其他位置将其停用后单击该表单时,计时器将重新初始化。

如果你有这个:

With New UserForm1
    .Show
End With

然后该TextBox1.Text属性没有被分配到正在显示的实例上,并且该框保持为空。然而,我们现在可以完全控制何时创建和销毁表单对象,现在我们可以处理Initialize事件(每个实例触发一次,当第一次创建对象时),因为我们知道表单对象刚刚创建......但是,表单将永远不会显示,因为唯一可用的线程正忙于那个Do...Loop,虽然它允许对话框的消息泵来泵送事件(感谢DoEvents),如果在该循环时没有显示表单输入,然后没有其他代码可以运行 - 因此,在Initialize处理程序中触发该循环将是一个非常糟糕的主意。

考虑考虑利用Application.OnTime来安排程序的执行:您想要做的是说“DoStuff在 1 秒内调用”,然后继续执行任何事情 - 不是忙循环,而是让表单的消息循环完成它的工作。有关许多示例之一,请参见这篇文章。


推荐阅读