Стиль VBA Macro On Timer для выполнения кода каждые заданное количество секунд, т.е. 120 секунд

36

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

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


ИЗМЕНИТЬ

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

Теги:
excel-vba
excel
timer
scheduling

7 ответов

56
Лучший ответ

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

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
  • 1
    спасибо за этот код :) это нужно для работы как можно скорее, и это была моя первая страница, чтобы перейти :) YAY
  • 0
    Привет, это даст ошибку, когда идентификатор листа Excel свернут или другой лист Excel открыт?
Показать ещё 3 комментария
20

Да, вы можете использовать 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) в модуле, а не в листе листа. Если у вас есть это в модуле рабочего листа, код требует небольшой модификации.

  • 0
    суб таймер выглядит как бесконечная рекурсивная функция; Если дескриптор OnTime не находится вне подпрограммы, подпрограмма будет сохранять ссылку на своего вызывающего до бесконечности.
8

В событиях рабочей книги:

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

  • 0
    Спасибо мужчина, я искал причину моей ошибки. Не поместил макрос в модуль. Теперь и мой код работает. Спасибо за объяснение. :)
2

(Это перефразировано из файлов справки MS Access. Я уверен, что XL имеет нечто похожее.) В принципе, TimerInterval является свойством уровня. После установки используйте субформат FormTimer для выполнения вашего предполагаемого действия.

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

Sub Form_Timer()
    'Do Stuff
End Sub
  • 0
    Спасибо за совет, однако я не хочу делать это как часть формы.
0
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

Код, о котором вы говорили выше, работает только в первый раз, но он должен звонить через каждые 120 секунд.

Что я должен сделать, чтобы работать с моим

0

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

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

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

  • 0
    Согласно статье CPearson, вам просто нужно остановить таймер (отменить ожидающее событие OnTime). Это устранит проблему «триггер события при закрытии книги», которую вы описали. Также в статье содержится предупреждение об использовании таймера Windows и изменении значения ячейки, что может привести к сбою Excel. OnTime требует меньше кода, просто обрабатывать правильно при использовании.
0

Мое решение:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню