Excel VBA计时器保持停止状态

时间:2014-10-08 18:51:13

标签: vba excel-vba excel

我目前有一个宏,当我点击用户窗体上的任意位置时,图片框会移到左侧。我已经添加了一个计时器,以便它在第一次表单点击后始终保持向左。问题是图片框确实向左移动,但只移动一次。之后,没有任何反应。到目前为止,这是我的代码:

Private Sub UserForm_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Call PlayerMoving
End Sub

Public Sub PlayerMoving()
   Player1.Left = Player1.Left + 5
   Call StartTimer
End Sub

Sub StartTimer()
    Application.OnTime Now + TimeValue("00:00:01"), "PlayerMoving"
End Sub

就像我之前提到的,在第一步之后,没有其他事情发生。我不知道为什么。我也试过像这样的do while循环:

Public Sub PlayerMoving()
do while SOME_STATEMENT_HERE
       Player1.Left = Player1.Left + 5
       Call StartTimer
loop

End Sub

2 个答案:

答案 0 :(得分:4)

好问题!答案就在于Application.OnTime功能。它旨在调用常规模块中的过程,而不是像表单这样的类对象。换句话说,OnTime函数无法找到您的PlayerMoving子函数,因为它位于您的表单类而不是常规模块中。

要解决此问题,您只需在常规VBA模块中添加以下包装函数:

Public Sub MoveMyPlayer()
    UserForm1.PlayerMoving
End Sub

然后更改OnTime来电以安排常驻模块中的MoveMyPlayer功能:

Public Sub StartTimer()
    Application.OnTime Now + TimeValue("00:00:01"), "MoveMyPlayer"
End Sub

另请注意,您的代码应该有一种方法可以在完成后停止计时器。您可能希望在表单中添加另一个函数,并在准备好停止移动图像时调用它:

Public Sub CancelTimer()
    Application.OnTime Now, "MoveMyPlayer", , False
End Sub

希望有所帮助!

亚当

答案 1 :(得分:1)

确保它们位于普通模块中(而不是用户表单模块)。修改以使用您的表单Name,以防它与UserForm1不同:

Public timerOn As Boolean

Public Sub PlayerMoving()
   UserForm1.Player1.Left = UserForm1.Player1.Left + 5
   Call StartTimer
End Sub

Sub StartTimer()

If timerOn Then
    Application.OnTime Now + TimeValue("00:00:01"), "PlayerMoving"
End If

End Sub

在您的UserForm模块中:

Sub UserForm_Activate()
    Player1.Left = 0 'Set the initial position if desired
    Module1.timerOn = False  '## Modify to the module name
End Sub
Private Sub UserForm_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Module1.timerOn = True
    Call PlayerMoving
End Sub

Sub UserForm_Terminate()
    Module1.timerOn = False
End Sub

可能有更好/更精确的方法来处理这个问题,但这是我提出的相对较快的方法。

所以我们创建一个布尔变量来确定是否保持“定时器”循环。我们在表单卸载时将其设置为false,并确保在重新激活表单时重置Player1.Left,否则它可能会“消失”。

然后,我们可以根据需要简单地切换此开关。