Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel VBA计时器不断停止_Vba_Excel - Fatal编程技术网

Excel VBA计时器不断停止

Excel VBA计时器不断停止,vba,excel,Vba,Excel,我现在有一个宏,当我点击用户窗体上的任何地方时,一个picturebox会移到左边。我已经添加了一个计时器,这样它在第一次表单单击后将一直向左移动。问题是picturebox确实向左移动了,但只移动了一次。之后,什么也没发生。这是我目前的代码: Private Sub UserForm_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) Call Pl

我现在有一个宏,当我点击用户窗体上的任何地方时,一个picturebox会移到左边。我已经添加了一个计时器,这样它在第一次表单单击后将一直向左移动。问题是picturebox确实向左移动了,但只移动了一次。之后,什么也没发生。这是我目前的代码:

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

结束Sub

好问题!答案在于
应用程序.OnTime
功能。它被设计为调用常规模块中的过程,而不是像表单这样的类对象。换句话说,
OnTime
函数找不到您的
PlayerMoving
sub,因为它在表单的类中,而不是在常规模块中

要更正此问题,只需在常规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
希望有帮助


Adam

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

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
在用户表单模块中:

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
,否则它可能会“消失”

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