Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2021 VBA - Event / RaiseEvent Comment ça marche ? Timer avec SetTimer()

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Dudu2

XLDnaute Barbatruc
Bonjour,
Malgré la lecture de la doc Microsoft je ne comprends toujours pas comment fonctionnent les "User Events". Et ça m' !

Je voudrais sortir le code "fonctionnel" du TimerProc() d'un SetTimer() exéctuté lorsque le Timer se déclenche car cela pose des problèmes et génère des erreurs selon les cas. Donc dans le TimerProc() je voudrais déclencher un évènement (un "User Event") qui exécute le code fonctionnel hors de l'environnement Timer.

Edit:
J'y suis finalement arrivé (fichier joint) mais cela ne peut pas fonctionner à partir d'un Module standard car on ne peut pas y déclarer une Classe WithEvents.
Faut donc être déjà dans une Classe ou un UserForm. Et au final je ne vois pas l'intérêt du truc vu qu'on peut faire un Call direct au lieu d'un RaiseEvent. Sauf pour les déclenchements multiples comme dans l'exemple de @Dranreb ci-dessous.
De toutes façons, rien ne prouve qu'un artifice de ce genre éviterait les erreurs du TimerProc() d'un SetTimer().

Donc ce post est parfaitement inutile !
Sauf éventuellement pour l'exemple fourni ci-dessous et les exemples de Timer avec SetTimer() en Post #8 et Post #9.
 

Pièces jointes

Dernière édition:
Bonsoir.
Regardez la classe Rythmeur et le module de service XRythmeur.
N'hésitez pas à me poser des questions si vous ne comprenez pas tout.
La solution passe par une méthode Actionner de l'objet qui déclenche l'évènement.
Encore faut-il dans le module standard de service avoir gardé un pointeur vers l'objet pour pouvoir l'invoquer.
 

Pièces jointes

Bonjour,

Ok, merci, j'ai bien vu:
- un RaiseEvent Intervient(Tic - Tac) dans la Classe Rythmeur,
- des Private WithEvents <nom classe> As Rythmeur dans des UserForms,
- des Private Sub <nom classe>_Intervient dans des UserForms.
Ça confirme ce que j'ai + ou - compris des User Events.

Je suppose que l'intérêt dans ton code est qu'à chaque RaiseEvent Intervient, ça déclenche tous les Private Sub <nom classe>_Intervient des UserForms.
 
L'intérêt c'est de pouvoir profiter d'un timer dans un module objet, vu que l'AddressOf à passer à un SetTimer n'accepte pas une méthode.
Oui, si un même exemplaire d'objet Rythmeur est connu WithEvents dans plusieurs modules objets. Personnellement je n'ai jamais fait ça.
RaiseEvent Intervient ne décrète l'évènement que pour son propre exemplaire, et la méthode Actionner qui l'effectue n'est invoquée que pour le seul exemplaire de Rythmeur qui a réclamé via la Function IdtRythmeurLancé cette Idt de lancement là, qui lui est propre.
 
Dernière édition:
De mon coté j'ai fait un Module_Timer pour gérer le SetTimer() qui dans sa TimerProc() appelle une fonction utilisateur à chaque déclenchement.
Fonction utilisateur qui peut être dans un Module standard ou Classe ou UserForm si déclarée Public et correctement qualifiée.

Le problème est qu'il faut "couvrir" l'appel de la fonction utilisateur par un On Error ce qui m'a longtemps questionné. D'où ce sujet.

En fait, la TimerProc() perd ses billes si certaines actions sont faites, par exemple clic d'un bouton Contrôle de Formulaire, sélection d'une cellule, modification d'une cellule et sans doute pleins d'autres cas. Et elle génère une erreur sur toute instruction qui ne relève pas strictement du code Timer. Ce qui empêche d'appeler la fonction utilisateur.
 
Dernière édition:
Au final j'ai fait une version qui gère les erreurs pour qu'on ait la garantie que la fonction utilisateur soit toujours appelée.

Edit: Fichier voir plus loin.
 
Dernière édition:
Salut,
en ne faisant que désactiver les erreurs dans TimerProc , cela n'a pas l'air de planter le Timer et Excel (essai avec Edition de cellule) pendant le blink.
VB:
'-----------------------
'CallBack Timer Fonction
'-----------------------
#If VBA7 Then
    Private Sub TimerProc(ByVal hWnd As LongPtr, ByVal wMsg As LongPtr, ByVal nIDEvent As LongPtr, ByVal dwTime As LongPtr)
#Else
    Private Sub TimerProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal nIDEvent As Long, ByVal dwTime As Long)
#End If
    Dim ErrNumber As Long
  
    If Not TimerID = 0 Then
        On Error Resume Next   
        'Execute the user function
        Application.OnTime Now, KeepUserFunction   
    End If
End Sub
Le seul problème qu'il semble y avoir c'est que la procédure cible ne s'exécute pas ( pas de blink pendant l'edition de cellule). Cela dépend de ce que l'on doit faire avec le Timer. N'importe comment on ne peut pas faire l'action par exemple quand il y a une édition de cellule). Si c'est pour un décompte ou un chrono , se baser sur le temps système pas sur un compteur en espérant que ce qui peut bloquer l'action avec le Timer ne dure pas trop longtemps.

Nullosse.
 
Dernière édition:
Il y a en effet le cas de l'édition de cellule que je sais détecter et peux traiter spécifiquement en temps d'attente.

Alors il y a 2 écoles:
1 - Gérer les erreurs et au bout d'un certain nombre d'erreurs répétées terminer le Timer (ma version modifiée avec le cas de l'édition de cellule)
2 - Ne pas gérer les erreurs et laisser le Timer tourner (ta version, ma version initiale)

Finalement tu as raison, c'est plus simple en option 2.
 

Pièces jointes

Dernière édition:
Cependant, cette version simplifiée pose un problème si le Timer doit être déclenché à espaces "longs", par exemple toutes les 3 minutes.
Une erreur retarde d'autant le déclenchement du Timer qui ne joue plus réellement son rôle car l'intervalle n'est plus respecté.
En cas d'erreur il doit être déclenché le plus tôt possible (disons 100ms) pour compenser le non appel de la fonction utilisateur sur l'erreur à l'échéance.

Alors je mets quand même ici la version qui gère les erreurs mais modifiée pour ne terminer le Timer à cause des erreurs que sur un nombre d'erreurs défini en Constante (modifiable) très grand.
 

Pièces jointes

Dernière édition:
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…