2014-10-08 4 views
2

В настоящее время у меня есть макрос, который, когда я нажимаю в любом месте пользовательской формы, картинка помещается влево. я добавил в него таймер, чтобы он всегда оставался слева после первого нажатия кнопки. Проблема в том, что кадр изображения перемещается влево, но только один раз. После этого ничего не происходит. Это мой код:Excel VBA Timer сохраняет остановку

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 

Как я уже упоминал, после первого хода ничего не происходит. Я не знаю почему. я также попробовал сделать во время цикла, как это:

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

End Sub

ответ

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 

Надежда, что помогает!

Адам

+0

Большое спасибо – HumanlyRespectable

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 при повторной активации формы, иначе она может «исчезнуть».

Затем мы можем просто переключить этот переключатель по мере необходимости.

Смежные вопросы