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

VB.NET Discussion :

Recherche de l'ecart minimal ou de l'egalite entre 2 valeurs affichées [Débutant]


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2005
    Messages
    608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2005
    Messages : 608
    Par défaut Recherche de l'ecart minimal ou de l'egalite entre 2 valeurs affichées
    Bonjour,

    Voici mon souci
    Dans un formulaire, j'ai une listbox appellée listQ comprenant des valeurs que j'appelle "nombre" allant de +1.00 à -2.00 au pas de 1/100 (donc, 1.00; 0.99; 0.98; ...; -2.00)
    lorsque je clique sur une valeur de la listbox, ceci declenche une sub calcul ayant pour fonction de trouver et d'afficher dans une textbox appelée TS une valeur decimale au 1/100.
    Ce calcul fonctionne tres bien et on voit donc que "nombre" et valTS sont liés par la sub "calcul" et si l'un bouge, l'autre bouge aussi.

    J'ai parallèlement, et issue d'une autre sub "calculadjust", une textbox appelée TSA qui affiche une valeur decimale au 1/100

    Mon but final est que ValTS et ValTSA soient egaux ou au pire les plus proches possibles, c'est à dire que ValTS varie pour s'approcher de ValTSA (qui, elle, ne bouge pas)
    Jusque maintenant, je procède manuellement, a savoir :
    exemple : j'ai ValTS = -2.04 et ValTSA = -2.69
    - je clique sur "nombre" de la listbox, ce qui fait varier ValTS jusqu'à avoir les deux valeurs au plus proche.
    - Je regarde alors la valeur de "nombre" dans la listbox et j'affiche celle ci dans une textbox resultat

    Je voudrais faire cela de maniere automatique via un button "calculate" qui declencherait l'operation

    j'ai essaye ceci en introduisant la notion d'ecart (pour l'instant sans afficher le resultat dans une textbox):

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Private Sub Automatique()
            Dim i As Integer, trouve As Boolean
            Dim ecartqfmin As Double ' plus petit écart
            Dim ecartqfactuel As Double  ' ecart actuel
            Dim indexecart As Integer ' index de l'écart dans ListQ
     
            ListQ.Visible = False
            trouve = False
            For i = 0 To ListQ.Items.Count - 1
                nombre = Convert.ToDouble(ListQ.Items(i).ToString)
                If Convert.ToDouble(TS.Text) = Convert.ToDouble(TSA.Text) Then
                    trouve = True
                    ListQ.TopIndex = i
                    ListQ.SelectedIndex = i
                    Exit For
                Else
                    ' on calcule l'écart entre TS et TSA
                    ecartqfactuel = Math.Abs(Math.Abs(Convert.ToDouble(TS.Text)) - Math.Abs(Convert.ToDouble(TSA.Text)))
                    If i = 0 Then
                        ' on calcule l'écart actuel en valeur  absolue. Comme c'est le premier écart il est automatiquement l'écart minimum
                        ecartqfmin = ecartqfactuel
                        indexecart = 0
                    Else
                        ' si ecartqfactuel < ecartqfmin alors ecartqfactuel devient ecartqfmin
                        If ecartqfactuel < ecartqfmin Then
                            ecartqfmin = ecartqfactuel
                            indexecart = i
                        End If
                    End If
                End If
            Next
            If trouve = False Then
                ' on n'a pas trouvé TS = TSA donc on prend au plus proche
                ListQ.TopIndex = indexecart
                ListQ.SelectedIndex = indexecart
                ' on relance le calcul avec la valeur de ListQ pointée par indexecart ( c'est le plus petit écart)
               calcul()            
    nombre = Convert.ToDouble(ListQ.Items(indexecart).ToString)
                End If
            ListQ.Visible = True
              End Sub
     
     Private Sub Buttoncalculate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Buttoncalculate.Click
    Automatique()
    End Sub
    mais rien ne fonctionne ni ne bouge,
    que pensez vous du code ????

    Merci bien

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Par défaut
    Bonjour,

    essaye déjà d'y aller en mode pas à pas voir ce qui se passe. (F10/F11)

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    700
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 700
    Par défaut
    Bonjour,
    l'idée est de parcourir les objets de la listBox dans l'ordre et de comparer l'écart au précédent.
    Tant qu'il diminue, on incrémente le numéro d'index et on stoppe dès l'inverse.
    Le dernier index est donc celui de l'élément cherché que l'on sélectionne dans la ListBox :
    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
    16
    17
    18
    19
    20
     Private Sub Automatique()
            'calcul de l'écart précédent en initialisant à sa valeur la plus grande.
            nombre = 1
            Dim ecartPrev As Double = calcul() - CDbl(TSA.Text)
            Dim indx As Integer = 0
     
            For Each it In ListQ.Items
                nombre = CDbl(it)
                Dim ecart As Double = calcul() - CDbl(TSA.Text)
                If Math.Abs(ecart) <= Math.Abs(ecartPrev) Then
                    indx += 1
                Else
                    Exit For
                End If
                ecartPrev = ecart
            Next
     
            ListQ.SelectedIndex = indx - 1
     
        End Sub

  4. #4
    Membre éclairé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2005
    Messages
    608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2005
    Messages : 608
    Par défaut
    merci beaucoup, je teste cela demain et reviens .....

  5. #5
    Membre éclairé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2005
    Messages
    608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2005
    Messages : 608
    Par défaut
    Bonjour a tousJe viens de tester en creant donc la sub "automatique" et en lancant cette sur depuis un button calculate2

    Rien de rien ne bouge, valTS ne bouge pas, et ma listbox ne bouge pas non plus de fait.

    Bien evidemment, le code n'accepte pas la sub calcul dans l'expression
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim ecart As Double = calcul() - CDbl(TSA.Text)
    mais même en remplacant par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim ecart As Double = CDbl(TS.Text) - CDbl(TSA.Text)
    rien ne bouge.

    Je n'ai pas d'erreur ni a l'execution ni en mode creation et en pas a pas, rien ne se passe

    pour voir ce qui se passait, j'ai crée nue textbox contenant 'ecart' et effectivement en cliquant sur calculate2, la valeur affichée dans ecart est bonne mais ma listbox affiche -2.00 alors qu'elle devrait afficher -1.31 ce que j'obtiens en manuel

    en fait le but est bien de ramener la valeur de TS le plus proche possible de celle de TSA et normalement, la valeur de 'nombre' dans la listbox devrait bouger toute seule puisque c'est ce qui se passe en manuel. Je suis carrément perdu la

  6. #6
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Par défaut
    Citation Envoyé par Attila54 Voir le message
    pour voir ce qui se passait, j'ai crée nue textbox contenant 'ecart' et effectivement en cliquant sur calculate2, la valeur affichée dans ecart est bonne mais ma listbox affiche -2.00 alors qu'elle devrait afficher -1.31 ce que j'obtiens en manuel

    en fait le but est bien de ramener la valeur de TS le plus proche possible de celle de TSA et normalement, la valeur de 'nombre' dans la listbox devrait bouger toute seule puisque c'est ce qui se passe en manuel. Je suis carrément perdu la
    D'où mon conseil d'aller voir ce qui se passe en pas à pas.
    Tu poses un point d'arrêt au début de ta fonction et tu regarde ligne par ligne ce qui se passe (F11), et dans 99.99% des cas tu trouves pourquoi ça ne va pas.

  7. #7
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Je viens de tiquer sur un truc...

    Dans ton programme, tu modifies effectivement l'index de ta liste, et vu vas effectivement rechercher la valeur calculée dans la textbox liée.

    Outre le problème évident de performances (conversion inutiles dans tous les sens), tu te heurtes à un autre problème...

    Lorsque tu modifies programmatiquement les contrôles d'une form, les événements associés sont lancés de façon asynchrone.

    Ceci veut dire que :
    - Si tu as un seul core, ou que ta machine est déjà chargée niveau CPU, aucun événement ne va être traité durant tes modifications (et donc la valeur contenue dans le textbox ne changera pas durant tout le traitement)
    - Si tu as plusieurs cores et que ta machine n'est pas trop chargée niveau CPU, les événements vont être traités, mais avec un délai possible : quand tu arrive à la 5° ligne, alors le textbox contiendra peut-être la valeur correspondant à la 2° ligne !

    Bref, ton approche n'est pas bonne.

    Déclare deux variables, contenant la première et la dernière valeur de ta liste sous forme de double.

    Ensuite, fait une boucle qui incrémente un compteur de la première valeur à la dernière valeur.

    Et fait le calcul "manuellement" (appelle la même méthode que celle qui est appelée dans le selectedindex_changed).

    Lorsque tu trouves la valeur qui donne le bon résultat, sélectionne la ligne dans ta listbox qui a la valeur correspondante.

    Ainsi, ton code devrait être à la fois plus rapide... et surtout, fonctionner !

    Une autre solution (pourrie) consite à mettre un DoEvents() après chaque changement d'index dans ta listbox. Ceci force le programme à exécuter les événements associés et d'attendre qu'ils aient fini.
    C'est contre-performant au possible, donc à éviter !

  8. #8
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    un truc me chagrine dans ton calcul d'écart :

    abs( abs(a) - abs(b) )

    => Si tu as -2 et 1.99 alors tu auras 0.01 comme écart, ce qui est complètement faux.

    Il faut faire :

    abs( a - b )

  9. #9
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par chrismonoye Voir le message
    Bonjour,
    l'idée est de parcourir les objets de la listBox dans l'ordre et de comparer l'écart au précédent.
    Tant qu'il diminue, on incrémente le numéro d'index et on stoppe dès l'inverse.
    Ça, c'est vrai pour une fonction linéaire. Pour un polynôme, ou autre fonction trigonométrique, il faudra tester l'ensemble des valeurs de l'intervalle.

    A noter aussi que dans ce cas, il est possible qu'il y ait plusieurs solutions.

    En tout cas, plutôt que de procéder ainsi, je re-sortirais mes cours de 1ère S afin de trouver pour quelles valeurs de X, Y prends la valeur recherchée.
    Ensuite, en testant à tout de rôle la valeur précédente et suivante dans ta liste, tu trouveras les valeurs de ta liste qui sont les plus proches.
    Cette approche me semble bien plus cartésienne, et permettra de continuer à utiliser ton code même si demain l'interval va de 10000000 à -10000000 avec un incrément de 0,00000001 (parce qu'actuellement, ton code mettrait plusieurs jours à trouver la réponse sur le plus gros serveur de la NASA sur un tel intervalle...)

  10. #10
    Membre éclairé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2005
    Messages
    608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2005
    Messages : 608
    Par défaut
    oulah stringbuilder, ce que tu dis est tres interessant mais vois tu, quand j'etais en premiere, la section S n'existait même pas cela doit faire 30 ans qu'ils sont aux oubliettes alors j'avoue avoir un peu de mal a suivre

    je vais quand meme pour commencer corriger les valeurs absolues pour etre plus mathematiquement correct

  11. #11
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Ta méthode "calcul()" fait quoi exactement ?

    (Parce que pour rechercher les valeurs en question, il faut déjà voir si on peut transformer ton code en une fonction arithmétique... genre si ça ramène le nombre de mots qui se trouve à la page X d'un livre, forcément, ça va être assez compliqué )

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 24/11/2008, 15h01
  2. [XPATH] Rechercher une valeur entre deux valeurs min et max
    Par icicmoi dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 27/10/2008, 13h12
  3. Recherche à partir d'un formulaire sur l'appuie sur Entrée
    Par talrashha dans le forum VBA Access
    Réponses: 1
    Dernier message: 29/07/2008, 14h41
  4. [Fonction]ecart entre 3 valeurs
    Par lolothom dans le forum VBA Access
    Réponses: 14
    Dernier message: 30/03/2007, 19h47
  5. [VB.NET] Recherche ds dg., valeur affiche ou non?
    Par Pleymo dans le forum Windows Forms
    Réponses: 9
    Dernier message: 08/02/2005, 22h21

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