IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Attendre qu'un recalcul soit effectué avant de continuer le code


Sujet :

Macros et VBA Excel

  1. #1
    Membre habitué
    Inscrit en
    Janvier 2004
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 173
    Points : 127
    Points
    127
    Par défaut Attendre qu'un recalcul soit effectué avant de continuer le code
    Bonjour,

    j'ai fait un programme vba qui modifie une cellule dont le contenu est un argument d'une fonction d'une cellule Excel. La fonction en question est une fonction Reuters, mais si on prend une fonction par défaut de Excel, c'est pareil. Imaginons donc le cas suivant :

    Dans A1, j'ai stocké la valeur 1
    Dans A2, j'ai stocké la valeur 2

    Dans A3, il y a la formule "=A1 + A2".

    Imaginons que je fasse un programme VBA dont une instruction modifie A2 (par exemple en mettant 3). Je souhaite que mon programme attende que la cellule A3 se mette à jour avant d'exécuter la ligne suivante. Est ce possible ?

    Juste pour ceux qui veulent comprendre pourquoi : le résultat renvoyé par la fonction Reuters est primordial pour la suite de mon programme. Dans le cas de la comme, l'actualisation est très rapide, mais dans le cas de la fonction Reuters, cela peut mettre une demi seconde, suffisament pour que le programme VBA soit déjà plusieurs lignes plus loin.

    Je précise que j'ai essayé d'insérer l'instruction suivante entre mes deux lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    application.wait now + TimeValue("00:00:01")
    mais le problème est qu'Excel arrête le recalcul des cellules pendant la seconde d'arrêt...

    Quelqu'un peut il m'aider ?

    Je vous remercie par avance.

  2. #2
    Membre averti Avatar de delphine35
    Femme Profil pro
    Analyste BO
    Inscrit en
    Novembre 2009
    Messages
    265
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Analyste BO

    Informations forums :
    Inscription : Novembre 2009
    Messages : 265
    Points : 377
    Points
    377
    Par défaut
    tu as essayé avec Calculate :

    Calculate
    ou
    Application.Calculate
    ou
    Worksheets(1).Calculate
    ou
    Worksheets(1).Rows(2).Calculate

  3. #3
    Membre habitué
    Inscrit en
    Janvier 2004
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 173
    Points : 127
    Points
    127
    Par défaut
    Merci Delphine pour cette réponse aussi rapide ! Impressionant !

    C'est ce que je suis en train d'essayer en ce moment. J'applique la fonction calculate sur la cellule qui contient la formule, mais ça ne change rien. Peut être faut il l'appliquer sur la cellule qui stocke la réponse. Je vais aussi essayer de recalculer tout le classeur, on ne sait jamais. Je te redis ça dans 5 minutes.

    EDIT : non malheureusement, ça ne fonctionne pas. J'ai inséré un calculate sur tout le classeur entre mes deux lignes. Je te remercie encore pour ta suggestion.

  4. #4
    Membre habitué
    Inscrit en
    Janvier 2004
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 173
    Points : 127
    Points
    127
    Par défaut
    J'ai trouvé une fonction programmée par quelqu'un d'autre qui permet de mettre en pause l'exécution de la macro sans arrêter les recalculs.

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Sub PauseTimer(ByVal nSecond As Single) 
    Dim t0 As Single 
         'temps de référence 
         t0 = Timer 
         'boucle d'attente 
         Do While Timer - t0 < nSecond 
               Dim dummy As Integer 
               dummy = DoEvents() 
               'si on dépasse minuit,il faut 
               'retrancher un jour 
               If Timer < t0 Then 
                   t0 = t0 - 24 * 60 * 60 
               End If 
         Loop 
    End Sub
    Je pense qu'il y a une solution plus élégante, mais en attendant, je vais utiliser ça.

  5. #5
    Inactif  
    Profil pro
    Inscrit en
    Février 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 517
    Points : 617
    Points
    617
    Par défaut
    salut

    et si tu essayais quelque-chose du genre :
    - relevé (dans une variable) de la valeur de ta cellule A3 avant l'appel de ta fonction
    - une boucle tant que la valeur de la cellule est égale au contenu de la variable :laisser la main au système, genre, donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    mavar = range("A3").value*
    'tes instructions d'ap^pel de fonction
     
    while range("A3").value = mavar
      doevents
    wend

  6. #6
    Membre habitué
    Inscrit en
    Janvier 2004
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 173
    Points : 127
    Points
    127
    Par défaut
    Merci babaothe pour cette suggestion. C'est une bonne idée...que j'avais malheureusement déjà testée et qui ne fonctionne pas. En fait, le programme boucle tout le temps car la mise à jour ne semble pas s'effectuer pendant que la boucle tourne. Mais je te remercie quand même pour ton idée.

  7. #7
    Membre habitué
    Inscrit en
    Janvier 2004
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 173
    Points : 127
    Points
    127
    Par défaut
    Je reviens vers vous car je n'ai toujours pas réussi à régler mon problème. Je croyais que j'allais pouvoir m'en tirer avec la fonction PauseTimer, mais en fait, elle bloque l'actualisation des cellules (en tout cas, la fonction Reuters ne se met pas à jour).

    J'ai une idée qui pourrait me convenir. Je voudrais ajouter un message pour dire à l'utilisateur que les opérations ont bien été effectuées. L'idée, c'est que le temps que l'utilisateur clique sur le bouton, la fonction Reuters se sera mise à jour. Le problème, c'est qu'avec un MsgBox, Excel s'arrête tant qu'on n'appuie pas sur le bouton OK. Ma question est donc la suivante :

    est il possible d'afficher un message en laissant les recalculs se faire ?

    Je vous remercie.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    262
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 262
    Points : 343
    Points
    343
    Par défaut
    Bonjour,

    Juste après la ligne qui te déclenche le calcul de ta fonction Reuters (Kesako???),

    essaie en insérant cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    While Application.CalculationState <> xlDone: Loop
    Peut-être????

    Bonne journée

  9. #9
    Membre habitué
    Inscrit en
    Janvier 2004
    Messages
    173
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 173
    Points : 127
    Points
    127
    Par défaut
    Merci mapeh pour cette suggestion. Je n'ai pas encore testé. Je te dirai ce que ça donne lundi.

    Pour ton information, Reuters est un logiciel qui fournit des données financières (par exemple, des historiques de cours de bourse...). Reuters, ce n'est pas le nom de la fonction.

    J'ai testé ta proposition Mapeh. Malheureusement, ça ne fonctionne pas. Par contre, j'ai trouvé un vieux sujet intéressant ici : http://www.developpez.net/forums/d69...ge-status-bar/. Le problème ressemble un peu au miens, sauf qu'il travaille avec une fonction bloomberg et non une fonction reuters...

    J'ai testé la solution qui avait fonctionnée ici (http://www.developpez.net/forums/d69...ge-status-bar/). Malheureusement, cela ne marche pas dans mon cas. Je me demande si ma fonction Reuters fonctionne comme une fonction Excel classique.

    En particulier, je ne suis pas sûr que ce soit Excel qui fasse le calcul, il ne fait peut être que recevoir les résultats. Voilà pourquoi je dis cela : lorsque je rentre la formule Reuters (=DeUpdate(D3315;C1;C2;;"";"LAY:HOR SOURCE:EQUITY REFRESH:NO TITLE CTU:CHANGED")), la cellule qui contient cette formule affiche "Retrieving..." dans un premier temps, puis les données qu'elle doit charger s'affichent dans d'autres cellules, et la cellule où se trouve la formule prend la valeur : "Fully retrieved at " + heure_du_chargement.

    C'est pourquoi, je voudrais en revenir à une piste que j'avais envisagée auparavant : est il possible d'attendre qu'un évènement ait lieu avant de continuer à exécuter le code ? Ca n'existe pas un évènement onChange pour une cellule ?

    Si cela était possible, je pourrais attendre que le contenu d'une cellule bien particulière change avant de continuer l'execution, ce qui réglerait mon problème.

    Je vous remercie par avance.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 14
    Points : 5
    Points
    5
    Par défaut
    Bonjour,


    Je suis dans la même situation que toi à l’exception près de la formule pour récupérer les données de reuters. En effet, j’utilise RSnap, peut être pas la même version de reuters. (version Wealth manager)

    Je te tiens au courant si je trouve une solution.

    De mon coté ça marche avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.OnTime Now + TimeValue("00:00:15"), "my_Procedure"
    J’espère que cela le fera pour toi

  11. #11
    Membre expérimenté Avatar de mayekeul
    Inscrit en
    Août 2005
    Messages
    1 369
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 1 369
    Points : 1 665
    Points
    1 665
    Par défaut
    bonjour,
    en essayant ça ça donne quoi?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    test = [A3].Value
     
    Do While test = Range("A3").Value
        Do Until Application.CalculationState = xlDone
     
        Loop
    Loop
    sinon il y a un moyen avec l'événement change de la sheet

    si ça t'intéresse...

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 288
    Points : 364
    Points
    364
    Par défaut
    Bonjour,
    une astuce qui pourrait marcher : encapsuler la fonction Reuters dans une fonction personnalisée.

    exemple :
    créer un module et y mettre sa fonction (ici je l'ai appelée Test, elle fait une somme)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Function Test(var1 As Currency, var2 As Currency)
        Test = WorksheetFunction.Sum(var1, var2)
        MsgBox "valeur de Test : " & Test  'il faudra mettre là la suite du code
    End Function
    Et dans la cellule concernée, à la place de la fonction Somme (ou Reuters pour toi), mettre =Test(A4;C4)

    Attention : la cellule se met à jour trop tard là aussi, c'est à dire après l'affichage de la msgbox dans mon cas, mais l'astuce est d'utiliser la variable Test dans la suite du code à la place du contenu de la cellule. Cette variable, elle, devrait être bien à jour même avec une fonction longue à exécuter (dans mon cas elle est à jour, mais la fonction Sum est rapide).

    Ceci dit il y a un problème potentiel : je ne suis pas sûr que la fonction de Reuters sera disponible en tant que WorksheetFunction, il faut tester et voir.

Discussions similaires

  1. Réponses: 1
    Dernier message: 22/06/2014, 18h37
  2. [PostgreSQL] Attendre la fin d'une requête avant de continuer le code
    Par renardchan dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 17/06/2011, 10h55
  3. Réponses: 19
    Dernier message: 13/01/2008, 23h33
  4. Attendre qu'une fenetre soit fermée avant de continuer.
    Par parp1 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 29/05/2007, 17h43
  5. Attendre qu'une tâche soit terminée avant d'en lancer une autre
    Par guidav dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 16/04/2007, 17h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo