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 :

Problèmes avec un tableau de données en "structure" [Débutant]


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Juillet 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Juillet 2018
    Messages : 5
    Par défaut Problèmes avec un tableau de données en "structure"
    Bonjour,

    Je suis nouveau en VB.Net et je m'excuse par avance pour les termes utilisés qui ne seraient pas "standards" du langage.
    Si je ne suis pas dans la bonne section, modérateurs déplacez cette demande. Merci.
    En quelques mots mon projet et mon problème.
    Je veux lire l'intégralité d'une base de données MySQL et la sauvegarder dans un tableau de structure.
    La lecture de la base ne me pose pas de problème mais la sauvegarde dans le tableau de structure ne veut pas fonctionner.
    Un bout de mon code:
    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
    Structure FicheDonnéesInsee
        Dim Id As String
        Dim Code_INSEE As String
        Dim Code_Postal As String
        Dim Commune As String
        Dim Département As String
    End Structure
    Public Class Gestion
        Dim DonnéesInsee() As FicheDonnéesInsee
     
        Sub DonnéesCommune()
     
            If cm.State = ConnectionState.Open Then
                Dim Idx As Integer = 1
                Dim cmd As New MySqlCommand("SELECT * FROM codes_insee", cm)
                Using L As MySqlDataReader = cmd.ExecuteReader()
                    While L.Read()
                        ReDim DonnéesInsee(Idx)
                        RetourDonneesInsee.Id(Idx) = L("Id")
                        RetourDonneesInsee.Code_INSEE(Idx) = L("Code INSEE")
                        RetourDonneesInsee.Code_Postal(Idx) = L("Code POSTAL")
                        RetourDonneesInsee.Commune(Idx) = L("Commune")
                        RetourDonneesInsee.Département(Idx) = L("Département")
                        Idx = Idx + 1
                    End While
                End Using
            End If
        End Sub
    ...
    J'ai une erreur sur chaque ligne de chargement de la structure "error BC30526: La propriété 'Chars' est 'ReadOnly'.".
    Malgré beaucoup de recherche, Je ne trouve pas comment lever ce défaut!

    Je vous remercie par avance de toute votre aide.
    Fréd

  2. #2
    Membre Expert Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Par défaut
    Bonjour,

    Il y a au moins une erreur dans ton code :
    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
     
       Sub DonnéesCommune()
     
            If cm.State = ConnectionState.Open Then
                Dim Idx As Integer = 1
                Dim cmd As New MySqlCommand("SELECT * FROM codes_insee", cm)
                Using L As MySqlDataReader = cmd.ExecuteReader()
                    While L.Read()
     
                        If Idx = 1 Then
                            ReDim DonnéesInsee(Idx)
                        Else
                            ReDim Preserve DonnéesInsee(Idx)
                        End If
     
                        RetourDonneesInsee.Id(Idx) = L("Id")
                        RetourDonneesInsee.Code_INSEE(Idx) = L("Code INSEE")
                        RetourDonneesInsee.Code_Postal(Idx) = L("Code POS
    Le premier "dimensionnement" du tableau doit se faire avec Redim et les suivants avec Redim Preserve, faute de quoi le contenu du tableau est détruit à chaque passage.


  3. #3
    Membre à l'essai
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Juillet 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Juillet 2018
    Messages : 5
    Par défaut Merci
    Merci Phil,

    Pour cette réponse très rapide. Effectivement c'est ok pour la gestion du tableau et après beaucoup de syntaxe l'index est sur l'élément structure et non une donnée.
    Après correction le code ressemble à:
    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
        Sub DonnéesCommune()
            If cm.State = ConnectionState.Open Then
                Dim Idx As Integer = 0
                Dim cmd As New MySqlCommand("SELECT * FROM codes_insee", cm)
                Using L As MySqlDataReader = cmd.ExecuteReader()
                    While L.Read()
                        If Idx = 0 Then
                            ReDim DonneesInsee(Idx)
                        Else
                            ReDim Preserve DonneesInsee(Idx)
                        End If
                        DonneesInsee(Idx).Id = L("Id")
                        DonneesInsee(Idx).Code_INSEE = L("Code INSEE")
                        DonneesInsee(Idx).Code_Postal = L("Code POSTAL")
                        DonneesInsee(Idx).Commune = L("Commune")
                        DonneesInsee(Idx).Département = L("Département")
                        Idx = Idx + 1
                    End While
                End Using
            End If
        End Sub
    Et c'est OK...
    Bonne journée, je ferme le sujet.
    Fréd

  4. #4
    Membre Expert Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Par défaut
    Merci pour le feedback ...

  5. #5
    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
    Bonjour,

    Je suis atterré que personne de censé n'est déconseillé à phoenix591 l'utilisation de tableau + redim !

    C'est un truc hérité de l'époques des dinosaures lorsque le VB 6 avait la part belle des développements sous Windows.

    De base, un array ça a une taille fixe.
    Ainsi, un redim ne fait rien de plus ni rien de moins que de créer un nouveau tableau de taille n + 1, puis recopier l'intégralité des lignes du tableau existant vers le nouveau tableau.
    Vu qu'ici on travaille sur une structure et non une classe, on effectue non pas une simple recopie de pointeur, mais une recopie de l'ensemble des éléments du tableau !

    Ca veut dire que :
    - on a besoin de 2 fois de plus de mémoire pour travailler
    - que si le tableau fait 1 Go en mémoire, rajouter une ligne va effectuer une recopie de 1 Go en mémoire !
    - pire, un tableau nécessite de l'espace mémoire contigüe, donc on a besoin à chaque fois de réorganiser massivement les données en mémoire pour libérer 1 Go de mémoire contigüe !!!!!

    https://docs.microsoft.com/fr-fr/dot...edim-statement
    Comportement
    • Remplacement de tableau. ReDim libère le tableau existant et crée un nouveau tableau avec le même rang. Le nouveau tableau remplace le tableau libéré dans la variable tableau.
    • Initialisation sans Preserve. Si vous ne spécifiez pas Preserve, ReDim initialise les éléments du nouveau tableau en utilisant la valeur par défaut pour leur type de données.
    • Initialisation avec Preserve. Si vous spécifiez Preserve, Visual Basic copie les éléments du tableau existant dans le nouveau tableau.

    Bref, une horreur absolue. VB 6 est mort, et c'est en grande partie à cause de ce genre de choses, qui on permit d'écrire des abominations.

    Bref.

    .NET permet depuis la version 1.1 de travailler avec des List de type générique.
    Ces listes, comme leur nom l'indique, sont des listes et non des tableaux.
    Par conséquence, leur taille est variable, et l'espace mémoire requis n'est pas contigüe.
    .NET apporteur un indexeur qui permet de les interroger comme un tableau, bref, les tableaux sont morts, vive les listes.

    Les seuls cas nécessitant des tableaux que j'ai pu rencontrer sont des buffers de bytes, soit pour manipuler des string avec encodage, soit pour lire/écrire en binaire dans des fichiers. Tous les reste du temps, les tableaux sont remplacés très avantageusement par des List.

    Enfin, j'ai un avis très mitigé concernant les structures. En effet, elles paraissent plus légères que les classes puisqu'elles n'embarquent pas de méthode (enfin... en .NET, si...) mais elles ont la contrepartie d'être des types valeur et non des types référence.

    C'est à dire que si vous omettez d'utiliser le motclé "byref" dans les méthodes qui vont les utiliser, alors vous allez passer votre temps à les recopier intégralement... ce qui est très contre-performant, et très souvent inutile (voir pire, très souvent gênant).

    A noter qu'ici, le type structure amplifie les effets de bord du redim sur un tableau, puisqu'au lieu de simplement recopier les références des lignes, on recopie effectivement le contenu de chaque ligne !

    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
     
    Structure Somme
        Dim A As Int
        Dim B As int
        Dim Total As Int
    End Structure
     
    Sub Calcul()
       Dim sum as Somme
       Dim res as Int
     
       sum.A = 2
       sum.B = 4
     
       res = Ajoute(sum)
       ' On a recopié tout pour rien
       ' Et contrairement à ce qu'on pourrait croire, sum.Total est égale à 0 (ou undefined, je ne sais pas comment marche VB.NET j'en fais jamais)
    End Sub
     
    Function Ajoute(somme as Somme) as Int
       ' Y'a pas de byref, du coup somme n'a rien à voir avec le sum de la procédure principale
       somme.Total = somme.A + somme.B
       return somme.Total
    End Function

    Donc on fait :
    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
     
    dim DonnéesInsee as list(of FicheDonnéesInsee)
     
    While L.Read()
        dim data as FicheDonnéesInsee
        data.Id = L("Id")
        data.Code_INSEE = L("Code INSEE")
        data.Code_Postal = L("Code POSTAL")
        data.Commune = L("Commune")
        data.Département = L("Département")
        DonnéesInsee.Add(data)
    End While
     
    ' Ensuite on manipule DonnéesInsee(idx) comme si c'était un tableau
    ' Et même sinon veut vraiment un tableau, on peut faire DonnéesInsee.ToArray() pour créer un vrai tableau (mais je n'en vois pas trop l'intérêt)

  6. #6
    Membre éclairé Avatar de Sam Placi
    Homme Profil pro
    Développeur occasionnel
    Inscrit en
    Octobre 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur occasionnel

    Informations forums :
    Inscription : Octobre 2019
    Messages : 68
    Par défaut
    Cherchez l'insensé ...
    Je suis atterré que personne de censé n'est déconseillé à phoenix591 l'utilisation de tableau + redim !
    Ce qui est vraiment atterrant, c’est qu’un « Expert éminent » donne une telle critique à posteriori (4 jours après la clôture de la discussion) alors qu’il ne s’est pas donné la peine d’intervenir en temps utile !
    Sans doute ne trouve-t-il pas utile de répondre à la question d’abord, après quoi ses conseils seraient bien venus, éventuellement …
    Sans doute oublie-t-il aussi que tous les outils peuvent trouver emploi à bon escient (ce n’est pas parce qu’aujourd’hui, on découpe des tôles à l’aide de laser, que la cisaille à main ou la scie à métaux n’est plus utile). Le choix d’un outil dépend de ses performances, bien sûr, mais aussi de sa rapidité de mise en œuvre. Si l’utilisateur n’a que quelques dizaines d’enregistrements à manipuler, ReDim peut convenir. La question de Phoenix591 de donne pas de précision sur ce point, son problème n’est là.
    Il est déplorable qu’un « Expert éminent » n’ait rien de mieux à faire de ses connaissances …

  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
    Pfiou, ben y'a des susceptibles ici.

    Je suis désolé de ne pas être omniscient.

    Pour ce qui est de la question initiale, j'y ai partiellement répondu en proposant une syntaxe qui fonctionne, et accessoirement, ayant déjà une réponse, je ne vois pas l'intérêt d'en refournir une autre.

    Par contre, entre l'utilisation de tableau, de redim et de structure, je vois clairement trois grosses erreurs qu'il me semble tout aussi importantes à corriger que le souci de syntaxe initial : aider quelqu'un à faire marcher son usine à gaz, j'appelle pas ça l'aider.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 21/03/2016, 16h07
  2. [C#] problème avec l'insertion des données dans MySQL
    Par madica dans le forum Accès aux données
    Réponses: 7
    Dernier message: 08/11/2005, 13h27
  3. problème avec un tableau dans un insert ...
    Par vbcasimir dans le forum Langage
    Réponses: 3
    Dernier message: 02/11/2005, 14h31
  4. problème avec ma base de donnée
    Par polace dans le forum PostgreSQL
    Réponses: 7
    Dernier message: 22/10/2005, 22h26
  5. problème avec ma base de données
    Par pmboutteau dans le forum ASP
    Réponses: 6
    Dernier message: 25/02/2005, 12h59

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