Création d'objets automatiques en VB.NET

Résolu
Bonjour,

Je suis en ce moment en stage et je dois créer un logiciel en VB.NET permettant de bloquer/débloquer des postes clients depuis un poste serveur.

Sur le poste serveur, une form regroupe 20 GroupBox qui représentent 20 postes (nombre de postes maximum à contrôler).
Chaque poste est enregistré dans une base de données.

Mon problème est que chaque GroupBox possède les mêmes fonctions (même requête, mêmes objets, ...) seul un numéro les différencient. Par exemple :

- dans la GroupBox1 il y a : nomposte1, compteur1, boutonbloquer1, prix1, requete1, ...
- dans la GroupBox2 il y a : nomposte2, compteur2, boutonbloquer2, prix2, requete2, ...
- dans la GroupBox3 il y a : nomposte3, compteur3, boutonbloquer3, prix3, requete3, ...
- et ainsi de suite jusqu'à 20

Voici un extrait de mon code :

'Pour le poste 1

Mycommand1.CommandText = "SELECT * FROM poste WHERE num_poste = 1;"
 
        'Déclaration du Reader1
        Dim myReader1 As OleDbDataReader = Mycommand1.ExecuteReader()
 
        myReader1.Read()
 
        Label1.Text = myReader1.GetString(1)
 
        If myReader1.GetString(1) = "-" Then
            bouton_stop1.Visible = False
        End If
...


'Pour le poste 2

Mycommand2.CommandText = "SELECT * FROM poste WHERE num_poste = 2;"
 
        'Déclaration du Reader2
        Dim myReader2 As OleDbDataReader = Mycommand2.ExecuteReader()
 
        myReader2.Read()
 
        Label2.Text = myReader2.GetString(1)
 
        If myReader2.GetString(1) = "-" Then
            bouton_stop2.Visible = False
        End If
...


L'idéal serait de faire un code de ce genre :

'Pour le poste i

While i <= 20

Mycommand(i).CommandText = "SELECT * FROM poste WHERE num_poste = " & i & ";"
 
        'Déclaration du Reader(i)
        Dim myReader(i) As OleDbDataReader = Mycommand(i).ExecuteReader()
 
        myReader(i).Read()
 
        Label(i).Text = myReader(i).GetString(1)
 
        If myReader(i).GetString(1) = "-" Then
            bouton_stop(i).Visible = False
        End If
...


Mais je sais que c'est impossible. N'y a t-il pas un moyen qui s'en rapproche ?

Merci d'avance.



--
La différence est le point commun à chaque individu.

13 réponses

Résumé de la discussion

Le problème porte sur la gestion de 20 GroupBox représentant chacun un poste, alors que toutes les GroupBox partagent les mêmes opérations et seules les identifiants changent. Une solution efficace consiste à boucler sur des contrôles nommés séquentiellement plutôt que de dupliquer le code pour chaque poste. Par exemple, tester 1 à 20 et activer/désactiver ou alimenter les valeurs via des chaînes de noms, comme GroupBox1, GroupBox2, etc., dans une boucle For. D'autres peuvent aussi extraire les données dans une structure de données et peupler les contrôles en une passe.

Bobot (l’IA à votre service)
  1. For i = 1 to 20

    Mycommand(i).CommandText = "SELECT * FROM poste WHERE num_poste = " & i & ";"

    'Déclaration du Reader(i)
    Dim myReader(i) As OleDbDataReader = Mycommand(i).ExecuteReader()

    myReader(i).Read()

    Label(i).Text = myReader(i).GetString(1)

    If myReader(i).GetString(1) = "-" Then
    bouton_stop(i).Visible = False
    End If

    Next i
    0
    1. Label1, MyReader1, bouton_stop1, ...
      Ce sont des objets donc la boucle n'est qu'un exemple pour expliquer ce que je veux mais elle est impossible.
      0
  2. Donc

    Dim obj as Object
    Dim i as Integer

    For each obj in TaCollectiondObjets
    i = obj.TonIndicedObjet

    - - - Ton code - - -

    Next
    0
    1. Par objet je veux dire que ce sont des labels, des boutons, des picturebox, ...
      C'est bien ça que tu as compris ?
      Si oui je ne comprends pas ton exemple peux-tu développer un peu plus s'il te plait ?
      0
  3. Je ne suis pas certain de bien comprendre ce que tu veux faire, mais si tu veux desactiver tout les objets d'un formulaires tu dois faire comme ça:

    (J'ai pas de VB.NET sous la main alors je ne suis pas certain de la syntaxe mais ca ressemble à ca)

    Dim obj as Object

    For each obj in Me.MonFormulaire.Controls

    obj.Visible =False

    Next
    0
    1. Non du tout ce n'est pas ça.

      J'ai 20 GroupBox qui remprésente chacune un poste client.
      Voila le code du poste 1 :

       'Requete SQL
              Mycommand1.CommandText = "SELECT * FROM poste WHERE num_poste = 1;"
      
              'Déclaration du Reader
              Dim myReader1 As OleDbDataReader = Mycommand1.ExecuteReader()
      
              myReader1.Read()
      
              Label1.Text = myReader1.GetString(1)
      
              If myReader1.GetString(1) = "-" Then
                  Label1.Text = myReader1.GetString(1)
                  bouton_stop1.Visible = False
              End If
      
              If myReader1.GetValue(5) = 1 Then
                  GroupBox1.Enabled = True
              End If
      
              If myReader1.GetValue(5) = 1 And myReader1.GetString(3) = "libre" Then
                  PictureBox1.ImageLocation = "libre_55_37.png"
              ElseIf myReader1.GetValue(5) = 1 And myReader1.GetString(3) = "occupe" Then
                  PictureBox1.ImageLocation = "occupe_55_37.png"
              ElseIf myReader1.GetString(3) = "down" And myReader1.GetString(1) <> "-" Then
                  PictureBox1.ImageLocation = "down_55_37.png"
              End If
      
              If myReader1.GetString(3) = "libre" Then
                  bouton_stop1.Visible = False
                  bouton_norm1.Visible = True
                  bouton_imprim1.Visible = True
              Else
                  bouton_stop1.Visible = True
                  bouton_norm1.Visible = False
                  bouton_imprim1.Visible = False
              End If
      
              'Fermeture du reader
              myReader1.Close()


      Comme tu vois, à chacun des objets il y'a le numéro associé (ici le numéro 1) : MyReader1, bouton_stop1, PictureBox1, ...

      N'est-il pas possible de mettre ce numéro comme variable puisque ce code est répété à 20 reprises et seul le numéro à la fin des noms des objets changent.
      0
  4. Quelque chose comme ca:

    For i = 1 to 20

    Me.Controls.Items("Label" & i.ToString).Visible = False
    Me.Controls.Items("PictureBox" & i.ToString).Visible = False
    Me.Controls.Items("bouton_stop" & i.ToString).Visible = False

    Next i

    En esperant que c'est plus près de ce que tu cherche
    0
    1. Oui c'est beaucoup plus près !
      J'ai testé mais une erreur se produit :

      La référence d'objet n'est pas définie à une instance d'un objet.
      0
  5. Link moi ton code et dis moi exactement à quelle ligne tu as ca
    0
    1. Voila le code ( c'est juste pour tester en fait) :

      Private Sub bouton_stop1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bouton_stop1.Click
      
              For i = 1 To 20
                  Me.Controls.Item("Label" & i.ToString).Visible = False
              Next i
      
      End Sub
      0
    2. et c'est à la ligne Me.Controls.Item ...
      0
  6. C'est que tu n'a pas les 20 Label: Label1, Label2, Label3, etc.
    0
    1. Je suis sûr d'avoir ces contrôles. J'ai testé avec les PictureBox même erreur. Le code que tu me proposes est exactement comme je veux mais il y a cette erreur.
      0
  7. Les controles font ils tous partie du meme formulaire que ton bouton: bouton_stop1?

    Car avec la commande Me, on refère à l'objet en cours (Formulaire en l'occurence)

    Si tes objets se trouvent dans d'autres formulaire, il ne faut pas utiliser Me
    0
    1. Oui tous mes objets font partis d'un même formulaire.
      0
  8. Je viens de m'installer VB.NET, nouveau projet, faire 20 labels et copier coller ton code test plus haut linké et ca marche... alors je sais plus :(
    0
    1. Met un point d'arrêt dans ton code (F9 sur la ligne qui bug) et vas y pas à pas. Ça bug au premier Label ou plus loin?
      0
      1. Bizarre ...
        J'ai mis le code au load du form.
        J'ai fais un debug et c'est au premier passage dans la boucle que ça bug.
        Comme c'est dans le load dès que le programme entre dans la boucle, il ne continue plus la suite des instructions et lance la fenêtre (sans exécuter la boucle et ce qui suit)
        0
    2. Items c'est en VB6 et VBA.... mon erreur désolé
      0
      1. Ah d'accord. J'utilise Visual Basic Express 2010 =S
        0
    3. Non finalement Item fonctionne encore en VB 2010. Mais si tu met ton code dans le Public Sub New du Form tu dois t'assurer de le mettre après le InitializeComponent
      0
      1. Deux questions :
        - Tu entends quoi par Public Sub New de Form ? Je n'ai que des Private Sub même pour le Load :

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


        Il faut que ce soit dans une Public Sub ?

        - Je connais pas du tout le InitializeComponent :s

        Par contre je te remercie pour l'aide et le temps que tu me donnes, c'est super sympa.
        0
    4. Ok j'avais mal lu. J'ai testé et dans le Form_Load de mon coté ca fonctionne.
      Envoi moi ton projet test: ftibo@usa.net
      0
      1. Ok pas de soucis ;)
        0
    5. Je t'ai répondu par courriel mais peux être que les serveurs de l'entreprise pour laquel tu travail ont interprétés ma réponse comme du spam et que tu n'a pas eu ma réponse alors je recidive ici. Essaye de mettre en commentaires ton bloc:

      GroupBox1.Enabled = False
      GroupBox2.Enabled = False
      GroupBox3.Enabled = False
      etc.

      et de le remplacer par:

      For i = 1 to 20

      Me.Controls("GroupBox" & i.ToString).Enabled = False

      Next i

      Dis moi ce que tu as
      1
      1. Je t'ai répondu par courriel ;)
        0
      2. Merci pour ta solution qui est parfaite ftibo.

        Cependant je n'arrive pas à utiliser le même principe pour les PictureBox.
        Je crois qu'ils ne font pas partie des contrôles.
        0