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

Windows Forms Discussion :

[VB.NET] Hashtable : mise à jour


Sujet :

Windows Forms

  1. #1
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut [VB.NET] Hashtable : mise à jour
    Bonsoir tout le monde.

    J'apporte ce soir un phénomène étrange. Enfin du moins, je ne le comprends pas

    Toujours dans mon programme de gestion pour compagnie d'autocar (certains commencent surement à me connaître ), j'ai dans le formulaire de confirmation d'une offre, la possibilité d'assigner jusqu'à 3 chauffeurs par cars.

    Pour ce faire, j'utilise une hashtable avec comme clé, le nom du car et comme objet, un tableau de strings contenant les noms des-dits chauffeurs ou des strings vident si aucun chauffeur n'a encore été affecté.

    L'affection des chauffeurs se déroule comme suit :
    • Sélection du car dans le composant ListView
    • Sélection des chauffeurs (jusqu'à 3) au moyen de 3 ComboBox


    Le bout de code que je vous montre ci-dessous est celui de la procédure appelée lorsque l'index sélectionné de la première ComboBox est modifié.
    (Il s'agit du même code pour les 2 autres ComboBox, il n'y a que la référence à la ComboBox qui change).

    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
    Dim arrayChauffeur() As String
            Dim i, j As Byte
     
            Try
                If verif_chauffeur(Me.cbChauffeur1.Text) Then
                    For i = 0 To Me.lvCars.Items.Count - 1
                        If Me.lvCars.Items(i).Selected Then
                            j = i
                        End If
                    Next
                    arrayChauffeur = chauffeurs1.Item(Me.lvCars.Items(j).Text)
                    arrayChauffeur(0) = Me.cbChauffeur1.Text
                    chauffeurs1.Item(Me.lvCars.Items(j).Text) = arrayChauffeur
                Else
                    MessageBox.Show("Vous avez déjà affecté ce chauffeur à un car.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    Me.cbChauffeur1.Text = ""
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
    Mon problème est que après l'exécution de bout de code, tous les éléments de la hashtable "chauffeurs1" ont été modifé et remplacer par le tableau "arrayChauffeur".

    J'ai vérifié en mode pas à pas et en affichant des messages. La clé est bien la bonne et tout n'a lieu qu'une seule fois. Je ne parviens pas à comprendre pourquoi tous les objets sont mis à jour.

    Merci d'avance à ceux qui pourront m'aider et aussi à ceux qui prendront la peine de lire ce message.

    Griftou.

    P.S. :

    Voici le morceau de code où la hashtable est initialisée.
    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
    Dim car As String
                car = dataRow.Item("CAR")
                'séparation de la liste des cars et mise en tableau
                Dim arrayCars() As String = Split(car, ";")
                'création du dictionnaire avec la capacité nécessaire
                chauffeurs1 = New Hashtable(arrayCars.Length)
                If dataRow.Item("CONFIRMEE") Then
                    Me.btnCancel.Enabled = True
                    Me.btnConfirmer.Text = "Enregistrer"
                    Me.tbAcompte.Text = Math.Round(Double.Parse(dataRow.Item("ACOMPTE").ToString), 2)
                    Me.dtpDate.Text = dataRow.Item("DATE_CONFIRMATION")
                    Dim chauffeursDB As String
                    Dim n As Byte
                    'récupération du champ chauffeur de la db
                    chauffeursDB = dataRow.Item("CHAUFFEURS")
                    'séparation du champ par car
                    Dim arrayChauffeurs() As String = Split(chauffeursDB, ";")
                    'remplissage du dictionnaire clé=plaque du car / objet=tableau de chauffeurs
                    For n = 0 To arrayChauffeurs.Length - 1
                        Dim arrayTmp() As String = Split(arrayChauffeurs(n), "&")
                        chauffeurs1.Add(arrayTmp(0), Split(arrayTmp(1), "|"))
                    Next
                Else
                    Dim n As Byte
                    Dim chf() As String = New String() {"", "", ""}
                    For n = 0 To arrayCars.Length - 1
                        Dim cars() As String = Split(arrayCars(n), "|")
                        chauffeurs1.Add(cars(0), chf)
                    Next
                    Me.btnConfirmer.Text = "Confirmer"
                    Me.dtpDate.Text = Today
                    Me.tbAcompte.Text = "0"
                End If
    Il a fallu que je "réorganise" ma DB après coup, c'est pourquoi la structure des champs peut paraître bizarre mais néanmoins logique. Je l'explique (ce qui expliquera le pourquoi de tous ces split) :

    Le champ CAR est de type string et structuré comme suit :
    • nom du 1e car
    • |
    • capacité du car
    • nom du 2e car
    • |
    • capacité du car
    • etc.....


    Concaténez les éléments et vous obtiendrez un exemple de ce que contient le champ CAR.

    Le champ CHAUFFEUR est de type string et structuré comme suit:
    • nom du 1e car
    • &
    • nom du 1e chauffeur
    • |
    • nom du 2e chauffeur
    • |
    • nom du 3e chauffeur
    • ;
    • nom du 2e car
    • &
    • nom du 1e chauffeur
    • |
    • nom du 2e chauffeur
    • |
    • nom du 3e chauffeur
    • etc.....


    Concaténez les éléments et vous obtiendrez un exemple de ce que contient le champ CAR.

  2. #2
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut
    Personne n'a une idée ?

    Griftou.

  3. #3
    Membre expérimenté Avatar de Mose
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 143
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 143
    Points : 1 379
    Points
    1 379
    Par défaut
    Moi y'en n'a pas causer VB, mais en exécution pas-à-pas, tu devrais voir la valeur qui est calculée et assignée aux cases de ta Hashtable.
    Hope this helps

  4. #4
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut
    Citation Envoyé par Mose
    Moi y'en n'a pas causer VB, mais en exécution pas-à-pas, tu devrais voir la valeur qui est calculée et assignée aux cases de ta Hashtable.
    Hope this helps
    Toi y'en n'a peut-être pas causer VB mais toi pas avoir lu message.

    Citation Envoyé par griftou
    J'ai vérifié en mode pas à pas et en affichant des messages. La clé est bien la bonne et tout n'a lieu qu'une seule fois. Je ne parviens pas à comprendre pourquoi tous les objets sont mis à jour.
    Plus sérieusement, j'ai déjà fait à maintes reprises l'exécution pas-à-pas. L'objet ajouté est bien celui qui doit l'être et la clé est bien la bonne. De plus, ce n'est fait qu'une fois. Mais cela n'empêche que tous les objets de la table sont modifés.

    C'est là qu'est mon problème, je ne comprends pas pourquoi.

    Griftou.

  5. #5
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    Salut griftou,

    Il est impossible dans une hashtable que la modification de la valeur d'une clé change la valeur des autres clés, pour la simple raison est que la hashtable stoque des clés unique. L'unicité dans ton cas est assurée par des clés en string.

    Donc forcement y a un autre probleme, je vais encore t'embeter et te demander de faire un petit breakpoint sur

    Citation Envoyé par code de griftou
    chauffeurs1.Item(Me.lvCars.Items(j).Text) = arrayChauffeur
    voir le continue de la collection juste avant et apres l'execution de cette ligne pour voi si le changement qui se fait sur toute la hashtable est causée par cette ligne.

    Une derniere chose je n'ai pas pu suivre à fond le deroulement de ton code mais j'ai un petit doute sur ca :

    Citation Envoyé par code de griftou
    For n = 0 To arrayChauffeurs.Length - 1
    Dim arrayTmp() As String = Split(arrayChauffeurs(n), "&")
    chauffeurs1.Add(arrayTmp(0), Split(arrayTmp(1), "|"))
    Next
    sûr de l'index 0 de ArrayTmp ?

    Voila A+

  6. #6
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut
    Citation Envoyé par mehdi_tn
    Il est impossible dans une hashtable que la modification de la valeur d'une clé change la valeur des autres clés, pour la simple raison est que la hashtable stoque des clés unique.
    Je suis bien d'accord avec toi. D'où mon incompréhension.

    Je testerai le breakpoint ce soir car je suis actuellement au boulot.

    Sinon, pour le arrayTmp(0), c'est correct.

    En fait, le champ de la DB se présente comme suit :

    car1&chauffeurA|chauffeurB;car2&chauffeurA|chauffeurB|chauffeurC;car3&chauffeurA

    J'effectue d'abord un split avec le ";" comme séparateur de manière à avoir chaque car et son (ses) chauffeur(s) dans le tableau arrayChauffeurs.

    J'effectue un second split avec le "&" pour chaque élément du tableau arrayChauffeurs pour avoir dans le tableau arrayTmp le nom du car et la liste des chauffeurs.

    J'affecte donc à mon hashtable des éléments étant des tableaux de string (split de arrayTmp(1) avec "|" comme séparateur) et ayant comme clé le nom du car (arrayTmp(0)).

    Voilà.

    Ai-je été clair?

    Griftou.

  7. #7
    Membre expérimenté Avatar de Mose
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 143
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 143
    Points : 1 379
    Points
    1 379
    Par défaut
    Sinon, solution canonique à tous les pb :
    * Quand un algo fait n'importe quoi, le décomposer en sous-algo connus.

    Ex : Au lieu de faire une Hashtable, tu fais temporairement deux ArrayList, une pour les valeurs, une pour les clefs.
    A la fin de ta méthode, tu fait un pti log pour y coller toutes tes valeurs et tes clefs.
    Tu rempli ta Hashtable avec le contenu des ArrayList
    Tu refais un log mais depuis la Hashtable

    Tu verras bien si le pb viens de cette méthode ou pas.

    En tout cas, +1 pour medhi : j'innocente la Hashtable direct ou je t'accuse d'avoir traffiqué ton framework

  8. #8
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut
    Je suis tout à fait d'accord avec vous. Je n'ai jamais dit que c'était la faute de la hashtable ^^. J'ai clairement fait une erreur quelque part. Le problème est de trouver où.

    Je viens donc de refaire une exécution pas à pas et j'ai découvert une piste.

    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
    Dim arrayChauffeur() As String
            Dim i, j As Byte
    
            Try
                If verif_chauffeur(Me.cbChauffeur1.Text) Then
                    For i = 0 To Me.lvCars.Items.Count - 1
                        If Me.lvCars.Items(i).Selected Then
                            j = i
                        End If
                    Next
                    arrayChauffeur = chauffeurs1.Item(Me.lvCars.Items(j).Text)
                    arrayChauffeur(0) = Me.cbChauffeur1.Text
                    chauffeurs1.Item(Me.lvCars.Items(j).Text) = arrayChauffeur
                Else
                    MessageBox.Show("Vous avez déjà affecté ce chauffeur à un car.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    Me.cbChauffeur1.Text = ""
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
    Dans le bout de code ci-dessus, au moment ou la ligne en rouge va être exécuté (cad celle qui est sensée mettre la hashtable à jour), tous les objets de ma hashtable contiennent déjà les nouvelles valeurs.

    Je cherche donc maintenant où cela peut-il se produire.

    Griftou.

    EDIT :

    Voilà, je viens de vérifier l'état de ma hashtable en exécution pas à pas après chaque ligne. La table est modifiée par la ligne juste au dessus de celle en rouge. Je n'y comprends vraiment rien du tout !!!

  9. #9
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut
    Je viens encore de revérifier parce que je n'en croyais pas mes yeux mais c'est bien ce qu'il se passe...

    Est-ce que quelqu'un aurait une idée du pourquoi ?

    Je vais résumer pour ceux qui n'auraient pas tout suivi.

    En clair, la question est :

    Pourquoi l'instruction en rouge dans le code ci-dessous modifie-t-elle les objets contenus dans la hashtable se nommant chauffeurs1 ?

    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
        Private Sub cbChauffeur1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbChauffeur1.SelectedIndexChanged
            Dim arrayChauffeur() As String
            Dim i, j As Byte
    
            Try
                If Me.cbChauffeur1.Text <> "" Then
                    For i = 0 To Me.lvCars.Items.Count - 1
                        If Me.lvCars.Items(i).Selected Then
                            j = i
                        End If
                    Next
                    If verif_chauffeur(Me.cbChauffeur1.Text, Me.lvCars.Items(j).Text, Me.cbChauffeur1.Name) Then
    
    
                        arrayChauffeur = chauffeurs1.Item(Me.lvCars.Items(j).Text)
                        arrayChauffeur(0) = Me.cbChauffeur1.Text        
                        chauffeurs1.Item(Me.lvCars.Items(j).Text) = arrayChauffeur
                    Else
                        MessageBox.Show("Vous avez déjà affecté ce chauffeur à un car.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                        Me.cbChauffeur1.Text = ""
                    End If
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub
    Que cette instruction ne modifie que l'objet assigné à arrayChauffeur pdt l'instruction précédent, j'aurais pu comprendre. Cela aurait pu être une espèce de "passage par référence" mais là, ce sont tous les objets qui sont modifiés.

    Quelqu'un sait ?

    Si non, auriez-vous une suggestion à me faire pour effectuer ce traitement sans utiliser de hashtable ?

    Merci d'avance.

    Griftou.

  10. #10
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    La seule truc qui peut causer ce probleme est que tu as inseré la meme reference d'un tableau pour la meme clé.

    Peux-tu verifier si toutes clés possedent deja les meme valeurs avant la modification

    Peux-tu nous montrer le code d'initialisation de la HT.

  11. #11
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut
    Le code d'initialisation de la hashtable se trouve dans mon premier message.

    Quand aux clés, j'ai déjà vérifié à maintes reprises, elles sont bien différentes.

  12. #12
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut
    Bon, finalement, j'ai résolu le problème en n'utilisant plus cette hashtable.

    J'ai créé une table supplémentaire dans ma base de données qui me permet de n'avoir à utiliser qu'un simple tableau de string.

    C'est un rien plus simple ^^.

    Je ne note pas ce topic comme résolu car je veux comprendre pourquoi ce problème à eu lieu.

    Bien à vous.

    Griftou.

  13. #13
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    je crois que ton probleme est là :

    For n = 0 To arrayCars.Length - 1
    Dim cars() As String = Split(arrayCars(n), "|")
    chauffeurs1.Add(cars(0), chf)
    Next
    Essai plutot, mais tu me promes d'essaye :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    For n = 0 To arrayCars.Length - 1
            Dim chf() As String = New String() {"", "", ""}
            Dim cars() As String = Split(arrayCars(n), "|")
            chauffeurs1.Add(cars(0), chf)
    Next
    Et excuse moi mais ajouter une table pour eviter un probleme de programmation n'est pas une tres belle idée.

    A+

  14. #14
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut
    Je suis d'accord que ce n'est pas la meilleure méthode pour résoudre un problème mais il faut bien avouer que le champ CHAUFFEURS qui se trouvaient dans ma table OFFRE ne ressemblait à rien du tout.

    Au moins maintenant, avec cette table CHAUFFEURS, ça ressemble à quelque chose.

    En fait, le truc des chauffeurs est une fonctionnalité qui a été ajouté plus tard par l'utilisateur sinon, j'aurais probablement créé cette table depuis le début.

    Pour ta solution, j'essaierai. P-e pas cette semaine parce que j'ai encore beaucoup de choses à faire mais j'essaierai. Je veux savoir pourquoi cette hashtable se mets à jour sur l'instruction "arrayChauffeur(0) = Me.cbChauffeur1.Text" alors qu'elle n'y fait même pas référence... (j'ai vérifié plusieurs fois pour être sûr, c'est bien sur celle-là qu'elle se met à jour).

    Donc voilà.

    Merci quand même à tous ceux qui ont consacré du temps à se problème.

    Griftou.

Discussions similaires

  1. vb.net - MySQL mise à jour d'un enregistrement
    Par gastoncs dans le forum VB.NET
    Réponses: 3
    Dernier message: 08/10/2012, 16h54
  2. Réponses: 2
    Dernier message: 22/05/2008, 15h07
  3. Réponses: 2
    Dernier message: 02/05/2006, 22h09
  4. [VB.NET][VS2003] mise à jour et .exe
    Par HULK dans le forum Windows Forms
    Réponses: 9
    Dernier message: 25/01/2006, 14h44
  5. Mise à jour Windows CE .NET
    Par G3G3 dans le forum Windows Serveur
    Réponses: 2
    Dernier message: 15/06/2005, 18h55

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