web-dev-qa-db-fra.com

Style VBA Macro On Timer pour exécuter le code toutes les secondes, c’est-à-dire 120 secondes

J'ai besoin d'exécuter un morceau de code toutes les 120 secondes. Je cherche un moyen facile de le faire dans VBA. Je sais qu'il serait possible d'obtenir la valeur de la minuterie à partir de l'événement Auto_Open pour éviter de devoir utiliser un nombre magique, mais je ne sais pas trop comment déclencher une minuterie pour que quelque chose se lance toutes les 120 secondes. 

Je ne veux pas vraiment utiliser une boucle infinie avec un sommeil si je peux l'éviter.


MODIFIER:

Répondez sur la base d’une réponse fournie à l’adresse: Excel VBA Application.OnTime. Je pense que c'est une mauvaise idée d'utiliser cette ... pensées de toute façon?

36
FinancialRadDeveloper

Lorsque le classeur s'ouvre pour la première fois, exécutez ce code:

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

Ensuite, ayez juste une macro dans le classeur appelée "EventMacro" qui va la répéter.

Public Sub EventMacro()
    '... Execute your actions here'
    alertTime = Now + TimeValue("00:02:00")
    Application.OnTime alertTime, "EventMacro"
End Sub
56
Alain

Oui, vous pouvez utiliser Application.OnTime pour cela, puis le mettre en boucle. C'est un peu comme un réveil où vous maintenez le bouton snooze enfoncé quand vous voulez qu'il sonne à nouveau. Ce qui suit met à jour la cellule A1 toutes les trois secondes avec l'heure.

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

Vous pouvez mettre la procédure StartTimer dans votre événement Auto_Open et changer ce qui est fait dans la procédure Timer (pour l'instant, il met simplement à jour l'heure dans A1 avec ActiveSheet.Cells(1, 1).Value = Time).

Remarque : vous souhaiterez obtenir le code (outre StartTimer) dans un module et non dans un module de feuille de calcul. Si vous l'avez dans un module de feuille de calcul, le code nécessite une légère modification.

21
Todd Main

Dans les événements du classeur:

Private Sub Workbook_Open()
    RunEveryTwoMinutes
End Sub

Dans un module:

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

Si vous voulez seulement que le premier morceau de code soit exécuté après le classeur s'ouvre, ajoutez simplement un délai de 2 minutes dans l'événement Workbook_Open

8
Alex P

(Ceci est repris des fichiers d'aide de MS Access. Je suis sûr que XL a quelque chose de similaire.) Fondamentalement, TimerInterval est une propriété de niveau formulaire. Une fois défini, utilisez le sous-formulaire Form_Timer pour exécuter l’action souhaitée.

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

Sub Form_Timer()
    'Do Stuff
End Sub
2
PowerUser

J'ai constaté que l'utilisation de OnTime peut être douloureuse, en particulier lorsque:

  1. Vous essayez de coder et le focus sur la fenêtre est interrompu Chaque fois que l'événement se déclenche.
  2. Vous avez plusieurs classeurs ouverts, vous fermez celui qui est censé utiliser le minuteur et il continue à déclencher et à rouvrir le classeur (si vous avez oublié de tuer l'événement correctement).

Cet article de Chip Pearson était très éclairant. Je préfère utiliser le minuteur Windows maintenant, au lieu de OnTime.

0
Gravity Grave

Ma solution:

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

Comment utiliser? Facile...

dummy= Cronometro(1) ' This starts the timer

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