Effectuer une boucle dans une procédure exploitant un calcul sur une feuille exc

Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014 - 22 févr. 2012 à 17:15
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 - 24 févr. 2012 à 13:17
Bonjour à tous; ça faisait bien longtemps que je n'étais pas passé sur ce forum...

Je suis actuellement en train de travailler sur une feuille de calcul Excel qui effectue des calculs en utilisant des fonctions natives d'excel.

Afin de chercher une solution optimale je dois créer mon propre solveur en effectuant une boucle sur une valeur qui se met à jour sur la feuille excel, puis reprendre le résultat par VBA, le comparer, et décider de la valeur suivante à utiliser pour le calcul.
Pour résumer:
- je lance la procédure VBA (avec un bouton)
- La procédure met une valeur dans une cellule de la feuille
- La feuille effectue un calcul à partir de cette valeur
- Je récupère le résultat du calcul par code
- En fonction d'une condition je spécifie la nouvelle valeur à prendre pour le calcul
- La boucle s'arrête dès que j'ai une erreur inférieure à 0.001 entre le résultat et une valeur cible.

Le problème que je rencontre est que le code en VBA est plus rapide que le calcul sur la feuille excel; le résultat n'est pas encore calculé que je suis à la boucle suivante.
Existe il un moyen de forcer l'attente du résultat de la feuille pour continuer le déroulement de la procédure ?

En vous remerciant d'avance pour l'aide.

38 réponses

Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014
23 févr. 2012 à 18:35
Je ne voulais pas poster mon code car je le change tout le temps pour essayer d'améliorer la convergence de mon calcul.
Voici où j'en suis

Sub Macro1()
'valeur de départ
ValDep = Range("c4").Value

'valeur de fin = 95%
'calcul de l'encadrement des pas de calcul
PasCalc = (0.95 - ValDep) / 50

For i = 1 To 50
Range("C30") = Range("C4").Value + (i * PasCalc)
Cells(i, 18) = Range("C36").Value
Cells(i, 20) = Range("C4").Value + (i * PasCalc)
Next i

Range("C30").Value = Range("U202").Value
ValApprox = Range("U202").Value - 0.01

'2eme passage
PasCalc = (((ValApprox + 0.01) - (ValApprox - 0.01)) / 50)

For i = 1 To 50
Range("C30") = ValApprox + (i * PasCalc)
Cells(i, 18) = Range("C36").Value
Cells(i, 20) = ValApprox + (i * PasCalc)
Next i

Range("C30").Value = Range("U202").Value


End Sub


Je fais varier la valeur d'entrée par pas variable (ici 50 pas) entre une valeur initiale et 95% (valeur maximale que peut prendre mon résultat).

Je fais un 1er passage pour rechercher l'erreur minimale entre mon résultat proposé et le résultat du calcul (avec la fonction =min de Excel) puis je refais une 2eme passe avec un pas plus faible pour améliorer la précision de mon résultat.
Par contre le traitement prend beaucoup de temps (il faut une 30aine de passes à 50 pas minimum pour obtenir toutes les données voulues), donc je vais continuer
Il se trouve en fait que l'utilisation des cellules de la feuille pour rechercher l'erreur minimale a permis de résoudre ce problème de "synchronisation", puisque chaque fois le code doit attendre que la recopie dans la cellule se fasse pour continuer.

Je vous remercie pour vos réponses.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
23 févr. 2012 à 18:39
Ce n'est pas du tout ni ce qui peut nous éclairer, ni ce que je t'ai demandé.
Tu devrais tout relire, calmement et avec soin.
En ce qui concerne
Je ne voulais pas poster mon code car je le change tout le temps pour essayer d'améliorer la convergence de mon calcul.

Voilà une raison de plus pour que je cesse de m'en mêler autrement que comme je l'ai fait dans mes réponses au-dessus.

____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014
23 févr. 2012 à 18:43
Ce n'est pas du tout ni ce qui peut nous éclairer, ni ce que je t'ai demandé.
Tu devrais tout relire, calmement et avec soin.


Je ne vois pas très bien ce que je peux poster de plus; tu as ici l'intégralité du code présent sur le classeur excel.
Je veux bien poster le fichier (si c'est possible) mais je ne suis pas sur que ça te serve à quelque chose.
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
23 févr. 2012 à 18:52
Il y quoi dans Range("U202").Value ?

Rataxes64
0

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

Posez votre question
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
23 févr. 2012 à 18:54
Mal dit!
Il y a quoi dans la cellule U202?


Rataxes64
0
Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014
23 févr. 2012 à 19:00
Il y a l'erreur minimale de toute ma série d'essais.
En fait le calcul ne peut être résolu directement, il faut faire des itérations.
Je vais donc modifier la valeur d'entrée de mon traitement, le calcul me délivre une valeur de sortie qui doit être égale à la valeur d'entrée si je suis tombé juste.
Je calcule la différence entre la valeur d'entrée et la valeur de sortie dans la cellule C36 (l'erreur), je recopie cette valeur sur une nouvelle ligne (dans la colonne 16), puis je vais rechercher l'erreur minimale (qui se calcule dans la cellule U202) puis récupérer la valeur d'entrée associée qui se copie sur la colonne 20.
Je refais une 2eme passe dans un encadrement de -0.01 à +0.01 autour de cette valeur d'entrée
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
23 févr. 2012 à 19:01
Il s'en sert probablement selon un mécanisme similaire à celui dont il se servait auparavant avec la cellule A2
Il est vraisemblable que U202 change de valeur en cours de route, via des formules (à nouveau).
Et c'est à nouveau le coup des feux et de l'agent de la circulation essayant en vain de ne pas se contrarier et de s'entendre alors qu'ils ne sont pas sur le même fil (la feuille étant quant à elle la circulation).


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
23 févr. 2012 à 19:16
Eh oui! Il y a bien une formule dans U202, on s'en serait douté..., et donc, pour reprendre l'analogie de ucfoutu, si le feu est au vert et que l'agent dit stop : il fait quoi le conducteur ?

Dans le code de la route, c'est prévu: l'Agent "l'emporte" sur le feu.
Dans le code de la route, oui, mais pas dans Excel!

Seule "bidouille" que j'ai vu : Ontime, et c'est pas gagné!

Rataxes64
0
Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014
23 févr. 2012 à 19:20
Merci pour cette proposition, je vais voir comment je peux utiliser cette instruction.
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
23 févr. 2012 à 19:22
Ah! Je pense aussi à Calculate (en jouant sur xlManual et xlAutomatic).
ucfoutu me reconaîtra bien là!
Mais ce c'est encore une "rustine".


Rataxes64
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
23 févr. 2012 à 19:55
"rustine" est le mot (plus exact que "pansement") et je suis content de voir qu'au moins quelqu'un s'est quelque peu reconnu.
Reste que "rustine" ou "pansement", onTime ou autre, l' "épée de Damoclès" continue à planer au-dessus de tout cela, même si le danger qu'elle nous tombe dessus est relativement faible.
Et c'est cet aspect-là, qu'il ne faut jamais perdre de vue.
Nous l'aurons tous compris : dur dur de traiter, sans que l'un ne puisse communiquer réellement avec l'autre (du moins à notre portée et dans la "mesure" de Excel) deux fils distincts en toute sécurité.
Ma conclusion ? ===>>
La voilà : ou tout traiter dans le fil des calculs de Excel (formules), ou tout traiter dans un fil VBA.
Et pour tout traiter dans un fil VBA : je ne vois aucune autre possibilité que de transposer en VBA tout ce que font les formules Excel utilisées.
Toute autre tentative ne serait qu'acrobatie et danger. Et "déporter" le problème d'une adresse à l'autre n'y changerait rien (ce n'est pas en déplaçant une crotte d'un endroit à l'autre qu'in la fait réellement disparaître, hein...)



____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
23 févr. 2012 à 20:17
Au fait, tu nous dis :
a permis de résoudre ce problème de "synchronisation"

Que doit-on comprendre ?
Tu as résolu ton problème?

Rataxes64
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
23 févr. 2012 à 20:31
D'accord avec toi en partie, ucfoutu,

Mais il y des cas, où le recours aux formules est d'une efficacité redoutable, notamment quand elles peuvent être mises en oeuvre en lieu et place d'une boucle For/Next.
Certes, c'est souvent au prix d'une certaine fatigne occulaire à force de saisie, mais question rapidité d'exécution, on est parfois agréablement surpris et récompensé du résultat.

Perso, si tout son classeur est "gavé" de formules, il vaudrait mieux "compléter" de ce côté pour yenter d'éviter ses boucles.

Et puis il y a aussi un "truc" auquel on ne pense pas toujours, c'est l'arrêt via une MsgBox vbYesNo et son bien utile If Response=VbYes...

Dudulle, où en es-tu?

Rataxes64
0
Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014
23 févr. 2012 à 20:39
Que doit-on comprendre ?
Tu as résolu ton problème?


Oui, au moins temporairement. La recopie des résultats semble correcte. Ce qui me gène est la vitesse d’exécution, mais je pense que je n'ai pas vraiment le choix.
Le traitement complet me semble très compliqué à faire totalement en code car j'ai recours à des tables de données, et effectuer les itérations sans code me semble également impossible (il en faut environ 3000 fois pour chacune de mes simulation).
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 févr. 2012 à 08:28
Le traitement complet me semble très compliqué à faire totalement en code car j'ai recours à des tables de données

Ce n'est pas une raison évidente.
Tout dépend de ce que font tes formules.
Je suis d'accord sur le fait que l'utilisation d'une formule peut simplifier la tâche du développeur.
Il est par contre clair que :
- il est assez rare que l'on ne puisse faire une procédure normale accomplissant ces tâches
- rien n'interdit d'utiliser dans une procédure normale, pour se simplifier la vie, des fonctions de Excel (la plupart d'entre elles sont utilisables à l'aide de l'objet WorkSheetFunction). Utiliser une fonction Excel à l'aide de l'objet WorkSheetFunction ne fait pas changer de fil et le résultat est dans VBA.

L'avantage serait, dans ton cas de figure, assez considérable :
Du fait que les calculs seraient faits dans le fil VBA, leur résultat serait connu de VBA et directement utilisables par VBA, alors que, comme tu t'y es pris, ils le sont uniquement dans le fil des calculs Excel et VBA ne peut les connaître ;
- avant qu'ils ne soient terminés
- qu'en allant lire (mais quand, pour être sûr qu'ils sont finis ?) la dernière cellule modifiée par les formules (ta cellule A2 devenue maintenant U202). Puisque même Excel étant tenu à l'écart de ce fil de calculs, l'évènement WorkSheet_Change ne saurait être déclenché et utilisé par VBA. Car là est bien le problème et la démonstration de ce qu'il s'agit de fils distincts ===>> pas d'évènement Change alors reconnu par Excel.



____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 févr. 2012 à 08:36
Ouvre ton aide VBA sur l'objet WorkSheetFunction ===>> lis ce dont il s'agit ===>> ouvre ensuite l'onglet "membres de WorkSheetFunction" ===>> regarde tout ce qu'il t'est possible d'utiliser (sans quitter VBA).
Tu devrais pouvoir t'en sortir avec çà.



____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
Dudulle32 Messages postés 42 Date d'inscription mercredi 10 mai 2006 Statut Membre Dernière intervention 31 janvier 2014
24 févr. 2012 à 12:38
Bonjour

En effet WorkSheetFunction semble tout a fait adapté pour mon application; il y a sans doute moyen de simplifier ce que j'ai déjà mis en place.
Merci pour cette proposition.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 févr. 2012 à 13:17
Bravo !
C'est là à mon sens la seule voie pro, compte tenu de ce que je devine de certains traitements.
Vas-y calmement.
N'hésite pas à revenir si, dans le cours d'une telle démarche, tu "tombes" sur une difficulté particulière. Expose-la alors techniquement et clairement et je t'aiderai à la surmonter avec joie.
Un dernier mot, en attendant : si tu as des plages de cellules contigües à traiter : n'hésite pas à les transformer en tableaux dynamiques et fais le traitement/calculs sur le(s) tableau(x) ainsi créés. Tu gagneras énormément en temps d'exécution.
Prends ton temps.
A bientôt.


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
Rejoignez-nous