Comment gerer une animation en VBA

Résolu
Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014 - 10 déc. 2012 à 19:44
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 - 11 déc. 2012 à 13:20
Bonjour à tous

Je voudrais réaliser des petites simulations interactives sur des classeurs VBA, dans un but pédagogique.
Pour ça j'ai besoin de gérer une sorte "d’horloge" qui va définir les pas de temps de mon animation.
A chacun de ces pas je vais lancer un bout de code qui va par exemple calculer le nouveau point d'une courbe, ou la position d'un objet, ou une valeur à afficher sur un schéma synoptique.

Pour obtenir cette horloge j'utilise ce code:

Private Sub CommandButton1_Click()
'bouton lancer la simulation

Range("A1") = 0
Call boucle
End Sub


Private Sub CommandButton2_Click()
'bouton arreter la simulation

Range("A1") = 1
End Sub



Sub boucle()
'corps de la simulation

Dim pausetime, start
intervalle = 0.02 'intervalle de l'horloge

'boucle de tempo
start = Timer
Do While Timer < start + intervalle
DoEvents
Loop

'stop la simu si A1 =1
If Range("A1") = 1 Then End

Range("C5").Value = Range("C5").Value + 0.05
Range("A2") = Range("A2") + 1
Call boucle


End Sub



Dans cet exemple je me contente d'augmenter la valeur d'une cellule à chaque intervalle de temps (mais ce n'est qu'un exemple).
J'obtiens ce que je veux, à un détail près ; le programme plante systématiquement au bout de 3137 boucles, avec le message "espace pile insuffisant".

Est ce qu'il y a un moyen d’empêcher ça ? Ou peut être une autre méthode que celle que j'utilise ?

Merci d'avance pour votre aide.

10 réponses

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
10 déc. 2012 à 23:20
Salut

Tu as tout, mais dans le désordre.
Private Sub CommandButton1_Click()
    'bouton lancer la simulation
    Range("A1") = 0
    Do While Range("A1") <> 1
        Call boucle
        Range("C5").Value = Range("C5").Value + 0.05
        Range("A2") = Range("A2") + 1
    Loop
End Sub

Private Sub CommandButton2_Click()
    'bouton arreter la simulation
    Range("A1") = 1
End Sub

Sub boucle()
    'corps de la simulation
    Dim pausetime, start
    intervalle = 0.02 'intervalle de l'horloge
    'boucle de tempo
    start = Timer
    Do While Timer < start + intervalle
        DoEvents
    Loop
End Sub

Conseils :
- L'indentation = espaces en tête de ligne, ne sont pas fait que pour faire joli mais pour permettre une lecture rapide d'un code.
- Tu dimensionnes (incomplètement) une variable 'pausetime' et ensuite, tu utilises 'intervalle' : Faut choisir

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
3
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
10 déc. 2012 à 20:44
Bonjour,
Rien de plus normal, dès lors que ta boucle ne cesse de s'appeler elle-même, sans fin ...
Tu devrais normalement entendre le ventilateur de refroidissement de ton processeur commencer à s'énerver


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
10 déc. 2012 à 23:14
Bonjour,

Normal, en coupant le code :
Sub boucle()

Call boucle

End Sub

Essayes plutôt d'utiliser une boucle Do/Loop ou une boucle For qui elle fera le timer et appellera la fonction.

v----Signature--------v----------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices.[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : ).[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualBasic (onglet Références dans les propriétés du projet).[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés/list
---
Mon site
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
11 déc. 2012 à 07:57
Bonjour, jack,
Oui, mais perd ainsi la "récursivité" qu'il veut (et qui est la cause du plantage).
Il ne pourrait réaliser son truc qu'à condition de se fabriquer un "timer" avec les 3 fonctions habituelles de l'Api de Windows (puisque son intervalle est inférieur à une seconde et qu'il ne peut donc envisager l'utilisation de Application.Ontime).

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014
11 déc. 2012 à 10:00
Bonjour et merci à tous pour vos réponses.

J'ai recopié le code de Jack, et ça ne plante plus, et le ventilateur de l'ordi ne s'emballe plus.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
11 déc. 2012 à 10:34
1) N'avais pas vu que boucle était périodiquement rappelé depuis CommandButton1_Click()
2)
et ça ne plante plus, et le ventilateur de l'ordi ne s'emballe plus.

Euh ... ===>> s'emballe plus loin, c'est vrai, mais finit par s'emballer.
Je ne suis définitivement pas d'accord avec cette méthode et vais te le montrer ===>>
Lance ===>> laisse travailler au moins une minute ===>> va dans le gestionnaire des tâches ===>> performances ===>> ouvre tes yeux
Toujours en laissant le gestionnaire des tâches ouvert (sur fenêtre performances) : arrête (en frappant 1 en cellule A1) et ouvre à nouveau tes yeux.
Ton "affaire" n'en est pas une du tout !
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
11 déc. 2012 à 11:25
Si toutefois tu persistais à utiliser cette méthode, reviens nous le dire.
Je ferais alors en sorte que on DoEvents soit un peu "remanié/revu" et qu'ainsi ton processeur soit significativement moins sollicité.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014
11 déc. 2012 à 12:56
Je suis ouvert à toute modification ; je suis conscient que ma solution tient surement plus de la bidouille.

En fait ce qui est absolument impératif c'est que je puisse utiliser des contrôles pour agir sur des valeurs d'entrée pendant que l'application tourne, pour voir comment évoluent les résultats de la simulation en temps réel.

On peut par exemple imaginer une simu simple avec une résistance qui chauffe une gamelle d'eau, l'utilisateur doit pouvoir jouer sur la puissance de la résistance (avec par exemple une barre de défilement), et voir comment la température évolue au fil du temps.
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
11 déc. 2012 à 13:14
Oui, un Timer utilisant les APIs serait plus indiqué.
Tu en trouveras le code parmi les sources en recherchant ... "timer VBA".
Juste un petit peu plus complexe, et encore.

La charge processeur dûe à une boucle Do-Loop+Doevents est un faux problème.
Le processeur tourne, certes pour rien, mais c'est son boulot.
Pratiquement aucun ralentissement d'application extérieure pendant ce genre de boucle. La seule chose désagréable, c'est qu'à chaque cycle de gestion des process, VBA reprend la main pour faire un tour de boucle Do-Loop. Rien de méchant.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
11 déc. 2012 à 13:20
Salut, jack,
Pas vraiment d'accord avec toi en ce qui concerne la charge du processeur.
Mais bon .. Puisque c'est la vouie choisiue, voilà donc de quoi la réduire d'environ de moitié, cette charge ===>>>
Private Declare Function GetInputState Lib "user32" () As Long

Private Sub CommandButton1_Click()
    'bouton lancer la simulation
    Range("A1") = 0
    Do While Range("A1") <> 1
        Call boucle
        Range("C5").Value = Range("C5").Value + 0.05
        Range("A2") = Range("A2") + 1
    Loop
End Sub

Private Sub CommandButton2_Click()
    'bouton arreter la simulation
    Range("A1") = 1
End Sub

Sub boucle()
    'corps de la simulation
    Dim pausetime, start
    intervalle = 0.02 'intervalle de l'horloge
    'boucle de tempo
    start = Timer
    Do While Timer < start + intervalle
      If GetInputState <> 0 Then DoEvents
    Loop
End Sub


Comme tu le vois, je n'ai fait que subordonner le doevents à une condition : qu'il ne concerne que ce qui est en cours.

Ce "pansement" ne signifie toutefois pas que j'approuve. Je ne fais là que "soulager" le patient.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
Rejoignez-nous