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

  1. #1
    Membre à l'essai
    VB NET - SELECT CASE - instructions "sautées" par le programme, pourquoi?
    Bonjour! Je viens quérir votre aide car j'ai un curieux souci avec une instruction "Select case" que j'utilise régulièrement.

    Voila, j'ai développé un mémori pour mon fils de 4 ans (pour l'occuper pendant le confinement). Je m'arrache depuis deux jours les cheveux sur un improbable problème. J'ai inséré un select case, mais le programme ne lance aucune instruction dans aucun cas.

    Il a 4 ans, il adore Sam Sam et la Patpatrouille, je lui ai fait plaisir en créant un jeu avec ses héros préférés (Chase, Stella...). Au début, je lui avais mis 9 personnages fixes. Et puis, comme rien n'est trop beau pour lui, je lui ai aussi permis de faire une partie "personnalisée" dans laquelle il choisit lui même des 9 héros sur une liste de 65 (ce que j'appelle sa "liste personnalisée").

    J'ai 18 boutons pour mes 18 cartes. Le programme génère un ordre aléatoire pour mes 9 paires de cartes et stocke donc l'ordre de sortie des cartes dans une list (of strings) appelée ListeNoms.
    Ensuite, il associe à chaque bouton/carte le héros qui lui correspond (en fonction du tirage qui a été fait (bouton 1: 1ere carte tirée, bouton 2: deuxième carte tirée, etc.) bref.

    Pour ne pas me retrouver avec un code à rallonge, j'ai créé une liste avec ses neuf héros choisis. En cas de partie personnalisée, le programme fait un tirage normal et remplace juste l'image de Chase par l'image de tel autre héros.

    Mon problème est tout bête: quel que soit le "Personnage" définit comme "String" (car je stocke son nom), la partie Select Case ne semble reconnaitre aucun cas de figure. J'ai testé en mettant des points d'arrêt un peu partout pour vérifier telle ou telle variable (avant la partie select case, dans la partie select case, après...). tout ce qui est avant s'execute, tout ce qui est après s'execute, mais ce qui est dedans... rien du tout

    toutes les variables renvoient toujours quelquechose: j'ai 9 héros dans ma ListeHéros (qui stocke les images des héros), le programme reconnait bien si c'est une partie personnalisée ou pas, j'ai bien 18 noms dans ma liste de noms (100% identiques à ceux que j'utilise dans mon select case), et pourtant... Walou...

    Voici mon code

    Code VB.NET :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
    Sub AffichageBoutons() 
     
            Dim ListePersonnalisée = 0
     
            If Me.CheckBox5.Checked = True And ListeHéros.Count = 9 Then ListePersonnalisée = 1 
     
            For i = 1 To 18
     
                Personnage = ListeNoms(i - 1)
     
                Select Case Personnage
     
                    Case "Chase"
                        If ListePersonnalisée = 1 Then
                            DirectCast(Me.Controls("Button" & i), Button).BackgroundImage = ListeHéros(0)
                        Else
                            DirectCast(Me.Controls("Button" & i), Button).BackgroundImage = WindowsApplication1.My.Resources.Chase
                        End If
     
                    Case "Stella"
                        If ListePersonnalisée = 1 Then
                            DirectCast(Me.Controls("Button" & i), Button).BackgroundImage = ListeHéros(1)
                        Else
                            DirectCast(Me.Controls("Button" & i), Button).BackgroundImage = WindowsApplication1.My.Resources.Stella
                        End If
                        End If
     
                    Case "Samsam"
                        If ListePersonnalisée = 1 Then
                            DirectCast(Me.Controls("Button" & i), Button).BackgroundImage = ListeHéros(2)
                        Else
                            DirectCast(Me.Controls("Button" & i), Button).BackgroundImage = WindowsApplication1.My.Resources.SamSam
                        End If
     
                    '............. etc ..................
     
                End Select
     
            Next
     
        End Sub


    En fait, le code se lit quand même car quand je met un Case Else, il "lit" ce qu'il y a dedans.

    Je n'y comprends plus rien. Help! j'utilise cette fonction très régulièrement, ça ne m'est jamais arrivé. Qu'est-ce qui peut bloquer?
    J'ai joint 2 screenshots avec deux points d'arret, pardonnez moi la familiarité, mais là, pour le coup, je me sens "teubé" Ici, un exemple avec "Chase". Il ne m'exécute absolument pas ce qui est dans le Cas Chase juste en dessous...



    Merci de votre aide. Je sèche!

    Bonne journée!

  2. #2
    Expert éminent sénior
    quel est le type de personnage ? de listenoms ? du mieux avec Select Case Personnage.ToString() ?

    .net est plus complexe qu'il en a l'air, ca peut arriver de tomber sur un truc incompréhensible
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre à l'essai
    Merci beaucoup de votre aide!

    Alors Personnage est défini comme string

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    Dim Personnage As String = ""


    ListeNoms est une list (Of string)

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
     Dim ListeNoms As New List(Of String)



    J'ai essayé avec Personnage.ToString. J'avais essayé aussi plus tôt CStr(Personnage). Rien du tout, je n'y comprend rien

    J'y regardais encore, je ne voyais aucune faute de syntaxe. C'est fou.


    Ma routine est déclarée comme Public. Est-ce que ça changerait quelque chose si je déclarais ma variable (Personnage) avec un Public? Elle marche très bien ailleurs comme çà ... Je suis mystifié.



    Pour info: j'ai essayé de lister tout le contenu de ma liste ListeNoms: ce sont bien des "strings", et comparables en tout point avec ceux déclarés dans mon select case.
    J'ai aussi essayé de lister les images de ma liste ListeHéros dans une picturebox que j'ai ajouté à la volée dans un coin de mon form pour voir: elles s'y affichent bien, et correspondent bien aux images des personnages qu'on veut afficher (à 100%). Impossible de les affecter à mon bouton. Et le plus fou, c'est que j'utilise la même sub routine ailleurs (un peu différente, mais à 90% identique), et ça passe impeccable... je crois que c'est le plus fou de toute cette situation .

  4. #4
    Expert éminent sénior
    quand tu es en point d'arret essaye shift f9 puis entre Personnage = "Chase" voir si ca répond true
    sinon Personnage.ToLower = "chase"
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre à l'essai
    Rho punaise... Tout est à "false" . Et pourtant, quand je vérifie le contenu de "Personnage", ça me renvoie "Chase"...



    Qu'est-ce que ça veut dire? Que ce n'est pas vraiment un String??? C'est fou quand même.

    Par contre, quand je fais Personnage = Personnage.ToString, il me met "True"

  6. #6
    Expert éminent sénior
    si si c'est bien un string, mais il peut contenir un caractère invisible qui fait que l'égalité est fausse
    genre si t'as mis les noms dans un fichier et mal découpé à la lecture du fichier ...
    saut de ligne par exemple c'est char(13) & char(10) (ou vbcrlf) si on découpé juste sur Lf ca découpe bien en ligne mais le char(13) reste, et est invisible

    dans shift F9 tu peux demander Personnage.ToCharArray() pour voir la liste des caractères
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Membre à l'essai
    J'y pensais à cette histoire de VbCrLf et compagnie. Je vais essayer ça.

    Ca y est. Je pense que tu as mis le doigt dessus...


    Il me dit qu'il fait 65.537 caractères de long, c'est ça?

    Si c'est le cas, j'ai peut être ma petite idée sur le pourquoi du comment. En fait ce ne serait pas en lien avec le problème pour lequel vous m'avez aidé récemment (et auquel je vous ai répondu en début d'après midi!) concernant un échange d'infos stockées dans des listes via TCP. J'avais fait une première version qui marchait très bien. Et puis je me suis dit "jouer à 2 c'est plus rigolo". C'est dans le cadre de ce projet que j'ai monté mon échange de contenu de Listes via TCP. Le contenu de la liste "ListeNom" est la copie sur un poste "client" d'une liste "ListeNom" sur une machine "serveur". En fait, la partie se lance bien sur le poste où l'appli tourne en serveur, elle tourne comme un charme, mais buggue justement sur le poste ou elle tourne en client. Ca ne viendrait pas de là? J'aurais pas transféré plus que nécessaire?

  8. #8
    Expert éminent sénior
    oui ca vient de là
    j'avais pas fait le lien, mais en regardant ton code dans l'autre thread tu fais

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    TCPClientStream.Read(rcvbytes, 0, CInt(TcpClientz.ReceiveBufferSize))

    or comme indiqué ici https://docs.microsoft.com/fr-fr/dot...ew=netcore-3.1
    cette fonction retourne le nombre d'octets réellement lu
    on donne un buffer de x octets, 8k couramment, et la méthode read remplit le buffer local avec ce qu'elle trouve dans le buffer de windows pour le réseau
    et à partir de ce retour (genre 5) on va ne va transformer en ascii que les 5 premiers octets

    comme je disais dans l'autres threads, maitriser le réseau demande un peu de temps ^^
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  9. #9
    Membre à l'essai
    Rhaaa punaise! Je me disais bien aussi que ça roulait un peu trop bien! Bon, ba j'ai encore du pain sur la planche dur dur d'apprendre par soi-même, mais en même temps, c'est ce que j'aime dans la démarche. C'est toujours frustrant quand ça coince, mais au final ça oblige à faire gaffe la fois d'après! Le côté apprenti sorcier finit toujours par envoyer dans le fossé. Je me suis bien fait rouler par l'apparente similarité de mes deux strings :

    Du coup il va falloir que je m'y prenne différemment. Poula, je ne sais pas trop par où prendre les choses du coup. Quelle ficelle devrais-je tirer en premier?

    Si j'essaie de remettre un peu d'ordre dans mes idées, en fait, s j'ai bien suivi, j'ai envoyé mes données + du "vide", donc j'ai récupéré des données + du "vide" , c'est ça? Donc ce qu'il lui manque, c'est combien d'octets il doit lire au lieu de tout le buffer, non? J'essaie d'y mettre du clair, c'est touffu pour le coup

  10. #10
    Expert éminent sénior
    non tu n'as pas envoyé 65000 octets

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    Dim rcvbytes(TcpClientz.ReceiveBufferSize) As Byte

    créé un tableau d'octet de la taille demandée (tu as du mettre 65k) les 65k octets valle 0 par défaut
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    TCPClientStream.Read(rcvbytes, 0, CInt(TcpClientz.ReceiveBufferSize))

    demande la recopie du buffer réseau dans ton tableau d'octet en partant de 0 et de maxi la taille du tableau (65k)
    (s'il y a plus d'octets que la taille max de ton tableau il faudra refaire .Read pour obtenir le reste des octets)
    cette méthode retourne un int qu'il faudrait stocker dans une variable et utiliser pour savoir combien d'octets sont arrivés, comme l'explique le lien précédent vers l'aide (F1 sur une méthode amène à l'aide qui est plutôt complète)
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    CatchMessage = System.Text.Encoding.ASCII.GetString(rcvbytes)

    transforme le tableau d'octet en string via le codage ascii, or tu as 65k octets dans ton tableau dont 95% à 0 (caractère invisible)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    Membre à l'essai
    Ah! Merci, j'y vois plus clair!! Des fois l'aide microsoft est un peu touffue pour l'oeil occasionnel, mais là avec tes explications, j'y vois beaucoup plus clair! Ce matin je m'y attaque, je vais essayer de suivre ton aide à la lettre! Voyons voir ce que je peux faire Ca a l'air plutôt clair dans ma tête, j'espère que ce sera aussi clair une fois en face du code. Go!

    Ok donc opération numéro 1, récupérer mon int pour savoir combien de kilos de données j'ai reçu.

  12. #12
    Membre à l'essai
    Alors, j'ai naïvement créé une variable Integer

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    Dim TailleDonneesReçues As Integer = 0


    que j'ai utilisée ainsi:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    TailleDonneesReçues = TCPClientStream.Read(rcvbytes, 0, ReceiveBufferSize.Length)


    comme dans l'exemple de l'aide (enfin, il m'a semblé que je pouvais m'appuyer dessus)

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length)


    C'est bien le retour de cette fonction que je dois récupérer, c'est ça?

    Parce que mon code n'y aime pas du tout. J'ai du faire les choses de travers. L'idée de stocker dans une variable, de mettre un breakpoint ou d'essayer d'y afficher dans une msgbox ne lui plait pas du tout. La machine qui envoie les données freeze aussitôt. En fait je crois que pour la machine qui reçoit, le script s'arrête ou "freeze" là. Si je mets un breakpoint sur catchmessage, il ne survient jamais.

    C'est pas ce qu'il fallait faire non? Quelle buse.
    J'ai fait un breakpoint, j'ai réussi à récupérer une valeur mais... je ne suis pas persuadé (du tout) que ce soit celle qu'on voulait au vu du résultat.



    Edit: en désespoir de cause, et comme je déteste rester sur un échec, je suis allé fouiner dans la doc, je suis tombé sur la propriété Available pour mon TCPclient. Ils disent: "Renvoie le Nombre d'octets de données reçus du réseau et disponibles pour la lecture". Je ne peux pas l'utiliser?
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    TailleDonneesReçues = TcpClientz.Available

    J'ai essayé. Ca ne bloque plus le code, mais je reçois toujours un 0 en retour . C'est parce que ça ne lit pas ce qui passe sur mon networkStream, c'est ça?

    Pourtant je reçois des données. Ca m'a mis le doute cette histoire. Du coup j'ai vérifié:
    - avant transfert de la part du serveur: ListeNoms.Count =0
    - après transfert du serveur: ListeNoms.Count=18 avec dedans mes 18 chaines (dopées au vide)
    Je dois vraiment pas checker le bon retour, mais j'avoue que je rame un peu.