Itération VBA

Résolu
conseilVBA Messages postés 25 Statut Membre -  
conseilVBA Messages postés 25 Statut Membre -
Bonjour,

Je suis débutante en VBA et je dois écrire une macro qui retrouve une variable par itération:

je connais P
je connais la formule pour trouver Px = ((2 * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8) / (-(Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) + ((Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) ^ 2 - 4 * ((T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt1 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt2) * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8)) ^ 0.5)) ^ 4 * 10) * 1000
Je connais toutes les variables sauf T et je veux le retrouver par itération.

La macro serait un peu comme ceci:
Tmin=-0.5
Tmax=100
Tant que P différent de Px
Alors T=100-Dx
et Px= ((2 * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8) / (-(Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) + ((Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) ^ 2 - 4 * ((T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt1 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt2) * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8)) ^ 0.5)) ^ 4 * 10) * 1000
retourner T quand P= Px

Si quelqu'un pouvait m'aider se serait super car ça fait une semaine que j'essaie sans trouver la solution.

Merci a tous

7 réponses

  1. lermite222 Messages postés 9042 Statut Contributeur 1 199
     
    Bonjour,
    Je ne suis certainement pas un "super doué" :ooo) mais avec une boucle d'itération tu devrais pourvoir y arriver ? et ça pourrait prendre un "certain temps"
    Note1 : Je comprend rien à ta formule mais là n'est pas le problème.
    Note2: ton explication est pas fort clair.
    A+
    1
  2. conseilVBA Messages postés 25 Statut Membre
     
    Bonjour lermite222,

    alors pour la note1: la formule n'est pas importante
    pour simplifier on peut dire que j'ai x= ay
    je connais x (placée en C5) et je veux trouver y(placée en C7)

    j'essaie de créer un programme qui fasse prendre plusieur valeur à y jusqu'a ce qu'il touve le bon x et qu'il me retourne cette valeur de y dans la cellule c7

    j'ai essayé avec la boucle tant que, Do..Loop

    mais je n'y arrive pas!!!

    ==> j'espère avoir été un peu plus clair?
    0
    1. lermite222 Messages postés 9042 Statut Contributeur 1 199
       
      Oui, mais quel est la grandeur de la variable ? ... 0,1 , 0,000001 ? où ???
      0
    2. conseilVBA Messages postés 25 Statut Membre
       
      les grandeurs des variables x et y sont de 0.01
      0
  3. ccm81 Messages postés 11033 Statut Membre 2 434
     
    bonjour

    Tant que P différent de Px me parait optimiste vu les calculs ...
    je crois qu'il vaudrait mieux, si E est l'incertitude sur Px souhaitée, quelque chose du genre
    T = TMax
    Tant que valeur_absolue(P-Px) > E  et T > TMin
      Px = Ta_formule
      T = T-Dx
    fin tant que
    si valeur_absolue(P-Px) < E 
    alors afficher T
    sinon afficher pas trouvé

    bon courage
    0
  4. conseilVBA Messages postés 25 Statut Membre
     
    Bonjour
    merci ccm81, ta macro fonctionne bien mais à chaque fois j'obtient "pas trouvé"
    je pense que c'est à cause du pas qui est trop grand
    voici un copier coller de la macro

    Sub Iteration()

    Pt1 = 1167.0521452767
    Pt2 = -724213.16703206
    Pt3 = -17.073846940092
    Pt4 = 12020.82470247
    Pt5 = -3232555.0322333
    Pt6 = 14.91510861353
    Pt7 = -4823.2657361591
    Pt8 = 405113.40542057
    Pt9 = -0.23855557567849
    Pt10 = 650.17534844798
    Tk = 273.15

    P = Range("c5")

    T = TMax
    While Abs(P - Px) > E And T > TMin
    Px = ((2 * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8) / (-(Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) + ((Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) ^ 2 - 4 * ((T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt1 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt2) * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8)) ^ 0.5)) ^ 4 * 10) * 1000
    T = T - Dx
    Wend
    If (P - Px) < E Then
    Range("c7") = T
    Else: Range("c7") = "pas trouvé"
    End If

    End Sub

    Que dois-je améliorer?

    Merci!
    0
    1. ccm81 Messages postés 11033 Statut Membre 2 434
       
      re
      as tu attribué une valeur à la précision souhaitée E, ici, je ne la vois pas donc, comme vba prend des initiatives, il prend E=0,et tu reviens au cas précédent !!!! ( commence par E assez grand pour tester puis diminue sa valeur vers la précision souhaitée pour ton résultat)
      bonne suite
      0
    2. ccm81 Messages postés 11033 Statut Membre 2 434
       
      RQ1. il te faudrait toujours declarer les variables utilisées
      Dim Pt1 as double
      etc ..
      RQ2 et pour eviter d'oublier tu commences toujours ton module (avant toute procedure) par
      Option Explicit
      RQ3. une fois que ça fonctionne pour une valeur de E,
      si pour une valeur de E plus petite, ça donne "pas trouvé" et que ça ne te convient pas, alors il faudra aussi diminuer le pas
      RQ4. Il y a aussi Dx, TMax et TMin qui n'ont pas de valeur
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. ccm81 Messages postés 11033 Statut Membre 2 434
     
    re
    dans la boucle tantque, la première fois qu'on rentre dans la boucle, Px n'est pas connue, donc il faut soit calculer une fois Px avant, soit, ce qui est préférable, utiliser une boucle jusqu'à

    initialiser TMin, TMax, Dx, E, et tes variables   
    T = TMax+Dx   
    do   
      T = T-Dx   
      Px = Ta_formule   
    loop until valeur_absolue(P-Px) < E or T < TMin   
    si valeur_absolue(P-Px) < E    
    alors afficher T   
    sinon afficher pas trouvé


    RQ. les remarques précédentes restent valables

    ce qui donne

    Sub Iteration()
    
    Const E = 0.1
    
    Dim Pt1, Pt2, Pt3, Pt4, Pt5, Pt6, Pt7, Pt8, Pt9, Pt10, Tk, Px, P
    Dim TMin, TMax, T, Dx
    
    Pt1 = 1167.0521452767
    Pt2 = -724213.16703206
    Pt3 = -17.073846940092
    Pt4 = 12020.82470247
    Pt5 = -3232555.0322333
    Pt6 = 14.91510861353
    Pt7 = -4823.2657361591
    Pt8 = 405113.40542057
    Pt9 = -0.23855557567849
    Pt10 = 650.17534844798
    Tk = 273.15
    
    P = Range("c5")
    TMin = -0.5
    TMax = 100
    Dx = 0.01
    
    T = TMax + Dx
    Do
      T = T - Dx
      Px = ((2 * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8) / (-(Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) + ((Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) ^ 2 - 4 * ((T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt1 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt2) * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8)) ^ 0.5)) ^ 4 * 10) * 1000
    Loop Until Abs(P - Px) < E Or T < TMin
    
    If (P - Px) < E Then
      Range("c7") = T
    Else
      Range("c7") = "pas trouvé"
    End If
    
    End Sub

    et avec les valeurs qui sont dans le code
    pour P = 750 ça donne T = 91.76

    bonne suite
    0
    1. conseilVBA Messages postés 25 Statut Membre
       
      re,

      alors tout d'abord un grand merci pour toutes tes remarques, j'en tiendrait compte pour le reste de mon programme.
      Ta macro fonctionne très bien
      J'ai quelques petites questions pour bien la comprendre et pouvoir faire de nouvelles itérations:

      Q1:
      T = TMax + Dx
      Je ne comprend pas à quoi sert la première ligne, est elle obligatoire?

      Q2:
      Do
      T = T - Dx
      Px = ((2 * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8) / (-(Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) + ((Pt3 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt4 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt5) ^ 2 - 4 * ((T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt1 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt2) * (Pt6 * (T + Tk + Pt9 / (T + Tk - Pt10)) ^ 2 + Pt7 * (T + Tk + Pt9 / (T + Tk - Pt10)) + Pt8)) ^ 0.5)) ^ 4 * 10) * 1000
      Loop Until Abs(P - Px) < E Or T < TMin

      là il s'agit de la boucle
      on commence par T = Tmax+Dx-Dx puis on enlève Dx à chaque boucle jusqu'à être infèrieur à E ou que T soit inférieur à Tmin?
      la dernière ligne donne en fait les conditions pour sortir de la boucle et ne pas planté le pc
      0
  7. ccm81 Messages postés 11033 Statut Membre 2 434
     
    re

    T = TMax+Dx   
    do   
      T = T-Dx   
      Px = Ta_formule   
    loop until valeur_absolue(P-Px) < E or T < TMin


    le T = T+Dx est une 'ruse' qui permet de commencer la boucle par T = T-Dx (donc, comme tu las compris, et comme ça doit être, la 1° valeur de T est Tmax) puis de calculer Px avec cette valeur de T
    et quand on sort de la boucle, si bien sur la valeur de Px est bonne, T contient la bonne valeur de T
    RQ1. si on voulait etre vraiment rigoureux, il faudrait même écrire
    T = TMax+Dx   
    do   
      T = T-Dx  
      if T >= TMin then 
        Px = Ta_formule
      end if 
    loop until valeur_absolue(P-Px) < E or T < TMin


    avant de calculer Px (on ne sait jamais, une valeur de T < TMin peut faire planter le calcul)
    ------------------------------------------------------------
    T = TMax 
    do   
      Px = Ta_formule 
      T = T-Dx 
    loop until valeur_absolue(P-Px) < E or T < TMin
    T = T+Dx


    ici, si la valeur en sortie de Px est bonne, T n'est pas la valeur correspondante et il faut ajouter après la sortie de boucle, un T = T+Dx pour rectifier
    comme c'est la bonne valeur de T qui t'interesse, il y a un choix a faire entre les deux méthodes
    RQ2. avec cette solution, la RQ1 précedente n'a plus lieu d'être, comme quoi .....
    ces pb controles de boucles tantque ou jusqua sont toujours un peu délicats à gérer

    bon courage pour la suite

    PS. si ce n'est pas indiscret, ta formule, elle sert à quoi?
    0
    1. conseilVBA Messages postés 25 Statut Membre
       
      D'accord je comprend mieux.
      Cette formule entre dans un programme de thermodynamique de l'air humide.
      Elle me sert à retrouver la température de mon air grâce à ma température de vapeur saturante!!
      En tout cas je te remercie pour ces informations, ça m'aide beaucoup!!
      0
    2. ccm81 Messages postés 11033 Statut Membre 2 434
       
      vaste programme
      si c'est fini pour moi, tu mets le pb a résolu
      bonne suite
      0
    3. conseilVBA Messages postés 25 Statut Membre
       
      ok je le met de suite

      merci
      0
    4. conseilVBA Messages postés 25 Statut Membre
       
      Bonjour ccm81,

      j'ai de nouveau un petit problème avec cette itération car pour être très précise il faut que l'ordinateur "réfléchisse" un long moment.
      Du coup, ce que j'avais pensé faire c'est de commencé la formule pour temp=50 et d'avoir un Dx= (1+(1-pvsx/pvs *0.1 )
      j'ai essayé avec cette macro:
      Function iterationT(Pvs)
      Const C = 0.000000000001


      Pt1 = 1167.0521452767
      Pt2 = -724213.16703206
      Pt3 = -17.073846940092
      Pt4 = 12020.82470247
      Pt5 = -3232555.0322333
      Pt6 = 14.91510861353
      Pt7 = -4823.2657361591
      Pt8 = 405113.40542057
      Pt9 = -0.23855557567849
      Pt10 = 650.17534844798
      Tk = 273.15
      TempMin = -0.5
      TempMax = 200
      TempMoy = 50
      Dx = (1 + (1 - (Pvsx / Pvs) * 0.1))

      Do
      Temp = Temp - Dx
      Pvsx = ((2 * (Pt6 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) ^ 2 + Pt7 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) + Pt8) / (-(Pt3 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) ^ 2 + Pt4 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) + Pt5) + ((Pt3 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) ^ 2 + Pt4 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) + Pt5) ^ 2 - 4 * ((Temp + Tk + Pt9 / (Temp + Tk - Pt10)) ^ 2 + Pt1 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) + Pt2) * (Pt6 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) ^ 2 + Pt7 * (Temp + Tk + Pt9 / (Temp + Tk - Pt10)) + Pt8)) ^ 0.5)) ^ 4 * 10) * 1000
      Loop Until Pvs - Pvs < C Or Temp < Tmin Or Temp > TempMax

      If (Pvs - Pvsx) < C Then
      iterationT = Temp
      Else
      iterationT = "pas trouvé"
      End If
      End Function




      mais l'ordinateur beuge à chaque fois...
      Est ce que tu vois d'ou l'erreur peut provenir?

      Merci
      0
  8. ccm81 Messages postés 11033 Statut Membre 2 434
     
    bonjour
    je ne suis pas chez moi, donc, je n'ai plus le pb sous la main, et pas trop le temps ..
    à priori je vois quelques erreurs
    1. avant la boucle do
    - Dx est calculé en fonction de pvsx qui, a ce moment n'a pas encore de valeur
    - C me parait bien petit
    -Temp n'a pas été initialisé (à TempMax ?)
    2. dans le controle, de la boucle (loop until ...)
    - le test pvs-pvs<C est problématique, 2 fois pvs et tester plutot la valeur absolue : abs(pvsx-pvs)
    - tu utilises TMin alors que c'est TempMin qui est initialisé plus haut

    RQ1. pour eviter d'utiliser des variables 'accidentelles' tu met Option Explicit en début de module, avec cette option, le compilateur refusera toute variable non déclarée
    RQ2. conséquence, tu devras déclarer toutes tes variables après la ligne de déclaration de la fonction (Dim Temp as single , etc ...)
    RQ3. les Ptx sont des constantes à déclarer comme C

    bonne suite
    0
    1. conseilVBA Messages postés 25 Statut Membre
       
      d'accord merci pour tes conseils..j'ai réussi à corriger l'itération
      Merci!
      0