OnTime

Comment faire fonctionner et arrêter proprement une macro lancée par OnTime ?

Application.OnTime(EarliestTime, Procedure, [LatestTime], [Schedule])
EarliestTime (valeur temps) Indique quand lancer la macro. C'est la programmation horaire. Pour lancer une macro à midi : EarliestTime = TimeValue ("12:00:00") Pour programmer une macro toutes les 5 mn : EarliestTime = Now + TimeValue("00:05:00")
Une fois que les premières 5 mn sont écoulées la macro s'exécute une fois, il faut donc de nouveau faire appel à OnTime pour les 5 mn suivantes, et ainsi de suite. (voir plus bas comment arrêter c'te maudit'affaire !)
Procedure (String) C'est la macro à exécuter
[LatestTime] (valeur temps) Optionnel Le temps maximal qu'Excel attendra pour exécuter ou non la macro (s'il n'est pas disponible).
Cette valeur est généralement calculée par rapport à EarliestTime, par ex : LatestTime = EarliestTime + 30 pour attendre 30 secondes. Attention : si Excel n'est pas prêt au bout de ce délai, la macro ne s'exécute pas ! Si ce paramètre est omis, Excel attend indéfiniment (recommandé).
[Schedule] (booléen) Optionnel Indique si la procédure doit être exécutée ou non. C'est le paramètre le plus curieux de la bande : D'abord parcequ'à l'inverse de tous les autres gentils booléens de la création, sa valeur par défaut est TRUE, ensuite parcequ'il est optionnel, ce qui compte tenu de son importance, est un peu illogique, enfin parce qu'il est pour le moins ombrageux. En effet, pour arrêter une procédure OnTime il faut lui repasser la dernière programmation horaire et mettre sa valeur Schedule à False. Cette opération génère une erreur (incompréhensible ?) qu'il n'est pas possible de contourner sans un On Error Resume Next.

En bref : OnTime fonctionne un peu comme si on disait à Excel "Attend jusqu'à 17:15 et Fait Job" donc, pour stopper l'affaire, il faut lui dire "Attend jusqu'à 17:15 et NeFaitPas Job" Ontime ne fonctionne pas comme un Wait perpétuel qui bouclerait sur lui-même, c'est pour cela qu'à la fin du "Job" il faut relancer la procédure appelant OnTime.
Cet exemple lance un pseudo-lecteur de message qui vérifie toutes les 30 secondes si il y a de nouveaux messages sur un réseau. Il est très largement inspiré par un code trouvé sur le forum Excel américain, j'ai hélas oublié le nom du gourou qui en est l'auteur mais qu'il en soit remercié néanmoins.

'En tête de module  
Option Explicit 
 Public RunWhen As Variant  'programmation horaire  
Public Const cRunIntervalSeconds = 30    ' 30 secondes  
Public Const cRunWhat = "LitMessage"  'nom de la sub à exécuter    

sub LanceLeLecteurDeMessage()
 'Programmation horaire = Maintenant + 30 secondes
 RunWhen = TimeValue(Now + TimeSerial(0, 0, cRunIntervalSeconds))
 Application.OnTime RunWhen, cRunWhat
 end sub
sub StoppeLeLecteurDeMessage()
 'Arrête le process en lui repassant la dernière programmation horaire
 On Error Resume Next
 Application.OnTime RunWhen, cRunWhat, , False
 end sub
sub LitMessage()
 Dim e
 'ici le code "actif" toutes les 30 secondes
 e = MsgBox("Pas de nouveau message !" & vbLf _
 & "Voulez-vous arrêter la veille du réseau ?", _
 vbQuestion + vbYesNo + vbDefaultButton2, _
 "Vérification des messages")
 If e = 7 Then  'Clic sur NON
 'Relancer le OnTime (et donc une nouvelle
 'programmation horaire)
 LanceLeLecteurDeMessage
 Else
 'Arrêter le OnTime
 StoppeLeLecteurDeMessage
 End If
 end sub

L'astuce est dans la redéfinition de RunWhen à chaque tour.
Astuce illustrée par ce classeur
fc-sauvegardeauto

Auteur :

Mots clefs associés à cette page : , , , , , ,