Стиль VBA Macro On Timer для выполнения кода каждые заданное количество секунд, то есть 120 секунд - PullRequest
38 голосов
/ 23 февраля 2010

Мне нужно запускать кусок кода каждые 120 секунд. Я ищу простой способ сделать это в VBA. Я знаю, что было бы возможно получить значение таймера из события Auto_Open, чтобы избежать необходимости использовать магическое число, но я не совсем понимаю, как запустить таймер, чтобы запускать что-то каждые 120 секунд.

Я действительно не хочу использовать бесконечный цикл со сном, если я могу избежать его.


EDIT

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

Ответы [ 6 ]

60 голосов
/ 03 декабря 2010

Когда книга открывается впервые, выполните этот код:

alertTime = Now + TimeValue("00:02:00")
Application.OnTime alertTime, "EventMacro"

Затем просто поместите в книгу макрос под названием «EventMacro», который будет повторять его.

Public Sub EventMacro()
    '... Execute your actions here'
    alertTime = Now + TimeValue("00:02:00")
    Application.OnTime alertTime, "EventMacro"
End Sub
22 голосов
/ 23 февраля 2010

Да, вы можете использовать Application.OnTime для этого и затем поместить его в цикл. Это что-то вроде будильника, когда вы нажимаете кнопку повтора, когда хотите, чтобы она снова зазвонила. Следующее обновляет ячейку A1 каждые три секунды со временем.

Dim TimerActive As Boolean
Sub StartTimer()
    Start_Timer
End Sub

Private Sub Start_Timer()
    TimerActive = True
    Application.OnTime Now() + TimeValue("00:00:03"), "Timer"
End Sub

Private Sub Stop_Timer()
    TimerActive = False
End Sub

Private Sub Timer()
    If TimerActive Then
        ActiveSheet.Cells(1, 1).Value = Time
        Application.OnTime Now() + TimeValue("00:00:03"), "Timer"
    End If
End Sub

Вы можете поместить процедуру StartTimer в ваше событие Auto_Open и изменить то, что делается в процедуре Timer (сейчас это просто обновление времени в A1 на ActiveSheet.Cells(1, 1).Value = Time).

Примечание : вам понадобится код (кроме StartTimer) в модуле, а не в модуле рабочего листа. Если он есть в модуле рабочей таблицы, код требует небольшой модификации.

8 голосов
/ 03 декабря 2010

В книге событий:

Private Sub Workbook_Open()
    RunEveryTwoMinutes
End Sub

В модуле:

Sub RunEveryTwoMinutes()
    //Add code here for whatever you want to happen
    Application.OnTime Now + TimeValue("00:02:00"), "RunEveryTwoMinutes"
End Sub

Если вы хотите, чтобы первый фрагмент кода выполнялся после , откроется рабочая книга, а затем добавьте задержку в 2 минуты в событие Workbook_Open

2 голосов
/ 23 февраля 2010

(Это перефразировано из файлов справки MS Access. Я уверен, что XL имеет нечто подобное.) По сути, TimerInterval - это свойство уровня формы.После настройки используйте sub Form_Timer для выполнения запланированного действия.

Sub Form_Load()
    Me.TimerInterval = 1000 '1000 = 1 second
End Sub

Sub Form_Timer()
    'Do Stuff
End Sub
0 голосов
/ 31 октября 2016

Я обнаружил, что использование OnTime может быть болезненным, особенно когда:

  1. Вы пытаетесь закодировать, и фокус на окне прерывается каждый раз, когда происходит событие.
  2. У вас открыто несколько рабочих книг, вы закрываете ту, которая должна использовать таймер, и она продолжает запуск и повторное открытие рабочей книги (если вы забыли правильно убить событие).

Эта статья Чипа Пирсона была очень яркой. Я предпочитаю использовать Windows Timer сейчас вместо OnTime.

0 голосов
/ 11 июня 2013

Мое решение:

Option Explicit
Public datHora As Date

Function Cronometro(action As Integer) As Integer 
'This return the seconds between two >calls
Cronometro = 0
  If action = 1 Then 'Start
    datHora = Now
  End If
  If action = 2 Then 'Time until that moment
    Cronometro = DateDiff("s", datHora, Now)
  End If
End Function

Как использовать? Легко ...

dummy= Cronometro(1) ' This starts the timer

seconds= Cronometro(2) ' This returns the seconds between the first call and this one
...