Comment gerer une animation en VBA [Résolu]

Dudulle32 42 Messages postés mercredi 10 mai 2006Date d'inscription 31 janvier 2014 Dernière intervention - 10 déc. 2012 à 19:44 - Dernière réponse : ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionContributeurStatut 11 avril 2018 Dernière intervention
- 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.
Afficher la suite 

Votre réponse

10 réponses

cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscription 28 août 2015 Dernière intervention - 10 déc. 2012 à 23:20
+3
Utile
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)
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_Jack
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionContributeurStatut 11 avril 2018 Dernière intervention - 10 déc. 2012 à 20:44
0
Utile
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.
Commenter la réponse de ucfoutu
NHenry 14179 Messages postés vendredi 14 mars 2003Date d'inscription 21 mai 2018 Dernière intervention - 10 déc. 2012 à 23:14
0
Utile
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
Commenter la réponse de NHenry
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionContributeurStatut 11 avril 2018 Dernière intervention - 11 déc. 2012 à 07:57
0
Utile
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.
Commenter la réponse de ucfoutu
Dudulle32 42 Messages postés mercredi 10 mai 2006Date d'inscription 31 janvier 2014 Dernière intervention - 11 déc. 2012 à 10:00
0
Utile
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.
Commenter la réponse de Dudulle32
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionContributeurStatut 11 avril 2018 Dernière intervention - 11 déc. 2012 à 10:34
0
Utile
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.
Commenter la réponse de ucfoutu
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionContributeurStatut 11 avril 2018 Dernière intervention - 11 déc. 2012 à 11:25
0
Utile
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.
Commenter la réponse de ucfoutu
Dudulle32 42 Messages postés mercredi 10 mai 2006Date d'inscription 31 janvier 2014 Dernière intervention - 11 déc. 2012 à 12:56
0
Utile
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.
Commenter la réponse de Dudulle32
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscription 28 août 2015 Dernière intervention - 11 déc. 2012 à 13:14
0
Utile
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.
Commenter la réponse de cs_Jack
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionContributeurStatut 11 avril 2018 Dernière intervention - 11 déc. 2012 à 13:20
0
Utile
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.
Commenter la réponse de ucfoutu

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.