Combobox, relation et bindingsource

edwinzap Messages postés 149 Date d'inscription samedi 29 septembre 2012 Statut Membre Dernière intervention 21 juin 2016 - 24 mars 2014 à 16:32
Cricri1670 Messages postés 32 Date d'inscription samedi 15 décembre 2007 Statut Membre Dernière intervention 10 avril 2014 - 10 avril 2014 à 16:28
Bonjour,
J'ai deux tables, T_ville dans laquelle se trouve des noms de villes et une table T_contact dans laquelle se trouve un champ ville. Le champ "ville" de la table T_contact est lié au champ "ref" (numéro automatique) de T_ville.
J'ai donc une combobox avec comme source la table T_ville. Lors d'un nouvel enregistrement, si je sélectionne une ville dans la combobox, le champ lié dans la table T_contact ne se remplit pas automatiquement.
Est-ce normal. Comment faire pour qu'il se remplisse?

8 réponses

Cricri1670 Messages postés 32 Date d'inscription samedi 15 décembre 2007 Statut Membre Dernière intervention 10 avril 2014
4 avril 2014 à 09:57
Bonjour,

Peux-tu me préciser comment tu as défini la liaison de données sur tes contrôles ? Quelles propriétés as-tu utilisé et vers quoi elles pointent ?

--
0
edwinzap Messages postés 149 Date d'inscription samedi 29 septembre 2012 Statut Membre Dernière intervention 21 juin 2016 2
6 avril 2014 à 14:16
Je vous répond le plus vite possible, demain sans doutes, car je n'ai pas le code sous la main pour l'instant.
En tout cas, merci beaucoup de vouloir m'aider, je croyais que c'était peine perdue ^^
0
edwinzap Messages postés 149 Date d'inscription samedi 29 septembre 2012 Statut Membre Dernière intervention 21 juin 2016 2
7 avril 2014 à 21:02
Pour plus de faciliter je vous mets mon projet en entier:
https://www.dropbox.com/s/dr2mqgbepaw2a9f/VisioSong.zip

Et voici les parties de codes que vous m'avez demander.
Je fais toutes les manip sur la base de donnée uniquement par code!

If My.Computer.FileSystem.FileExists(My.Application.Info.DirectoryPath & "\Chants.mdb") Then
                con.ConnectionString = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & My.Application.Info.DirectoryPath & "\Chants.mdb"
            Else
                MsgBox("Connection à chants.mdb impossible !" & Chr(13) & "Fichier introuvable à l'emplacement:" & Chr(13) & My.Application.Info.DirectoryPath, MsgBoxStyle.Critical)
                Me.Close()
            End If

            Dim sql_chant As String
            Dim sql_paroles As String
            Dim sql_répertoires As String

            sql_chant = "SELECT * FROM T_Chant"
            cmd = New OleDbCommand(sql_chant, con)
            cmd.Connection.Open()
            da_chant.SelectCommand = cmd
            da_chant.FillSchema(ds, SchemaType.Source, "T_chant")
            da_chant.MissingSchemaAction = MissingSchemaAction.AddWithKey
            da_chant.Fill(ds, "T_Chant")
            cmd.Connection.Close()

            sql_paroles = "SELECT * FROM T_Paroles"
            cmd = New OleDbCommand(sql_paroles, con)
            cmd.Connection.Open()
            da_paroles.SelectCommand = cmd
            da_paroles.FillSchema(ds, SchemaType.Source, "T_chant")
            da_paroles.MissingSchemaAction = MissingSchemaAction.AddWithKey
            da_paroles.Fill(ds, "T_Paroles")
            cmd.Connection.Close()

            sql_répertoires = "SELECT * FROM T_Répertoires"
            cmd = New OleDbCommand(sql_répertoires, con)
            cmd.Connection.Open()
            da_repertoires.SelectCommand = cmd
            da_repertoires.FillSchema(ds, SchemaType.Source, "T_Répertoires")
            da_repertoires.MissingSchemaAction = MissingSchemaAction.AddWithKey
            da_repertoires.Fill(ds, "T_Répertoires")
            cmd.Connection.Close()


            Dim R_ChantParoles, R_ChantRépertoires As DataRelation
            Dim ChantRef_Column, ParolesNum_Column, RépertoireRef_Column, ChantRépertoire_Column As DataColumn

            ChantRef_Column = ds.Tables("T_chant").Columns("ref")
            ParolesNum_Column = ds.Tables("T_Paroles").Columns("N_Chant")
            ChantRépertoire_Column = ds.Tables("T_Chant").Columns("Répertoire")
            RépertoireRef_Column = ds.Tables("T_Répertoires").Columns("N°")

            R_ChantParoles = New DataRelation("R_ChantParoles", ChantRef_Column, ParolesNum_Column)
            R_ChantRépertoires = New DataRelation("R_ChantRépertoires", RépertoireRef_Column, ChantRépertoire_Column)

            ds.Relations.Add(R_ChantParoles)
            ds.Relations.Add(R_ChantRépertoires)

            R_ChantRépertoires.ChildKeyConstraint.DeleteRule = Rule.SetNull
            R_ChantRépertoires.ChildKeyConstraint.UpdateRule = Rule.Cascade

            Répertoires_BindingSource.DataSource = ds
            Répertoires_BindingSource.DataMember = "T_répertoires"

            Chant_BindingSource.DataSource = ds
            Chant_BindingSource.DataMember = "T_chant"

            Paroles_BindingSource.DataSource = Chant_BindingSource
            Paroles_BindingSource.DataMember = "R_ChantParoles"

            ListBox_Chants.DataSource = Chant_BindingSource
            ListBox_Chants.DisplayMember = "Titre"
            TextBox_Titre.DataBindings.Add(New Binding("text", Chant_BindingSource, "Titre"))
            TextBox_AuteurMusique.DataBindings.Add(New Binding("text", Chant_BindingSource, "Auteur_Musique"))
            TextBox_AuteurParoles.DataBindings.Add(New Binding("text", Chant_BindingSource, "Auteur_Paroles"))
            TextBox_Code.DataBindings.Add(New Binding("text", Chant_BindingSource, "Code"))
            TextBox_Remarques.DataBindings.Add(New Binding("text", Chant_BindingSource, "Remarques"))
            TextBox1.DataBindings.Add(New Binding("Text", Chant_BindingSource, "Répertoire"))

            ComboBox_Répertoire.DataSource = Répertoires_BindingSource
            ComboBox_Répertoire.DisplayMember = "Répertoire"

            ComboBox_Repertoires.DataSource = ds.Tables("T_répertoires")
            ComboBox_Repertoires.DisplayMember = "Répertoire"

            DataRepeater_Paroles.VirtualMode = True
            BindingNavigator_Paroles.BindingSource = Paroles_BindingSource
            DataRepeater_Paroles.DataSource = Paroles_BindingSource
            TextBox_Paroles.DataBindings.Add(New Binding("text", Paroles_BindingSource, "Paroles"))
            ComboBox_Paroles.DataSource = Paroles_BindingSource
            ComboBox_Paroles.DisplayMember = "type"
0
Cricri1670 Messages postés 32 Date d'inscription samedi 15 décembre 2007 Statut Membre Dernière intervention 10 avril 2014
8 avril 2014 à 18:14
Bonjour,

Le lien vers le projet complet... bof !
Faut pas oublier que beaucoup de personne demandent de l'aide et que le temps de ceux qui répondent n'est pas extensible...
Il est important d'essayer d'être précis et concis dans les questions. Il faut éviter de livrer du code qui fonctionne et qui n'est pas en relation directe avec ton problème.

J'ai jeté un oeil rapide à ton code. Déjà, je le trouve clair. Par contre, je te suggère d'inverser l'ordre de définition des propriétés DataSource et DataMember/DisplayMember. Ne me demande pas pourquoi mais j'ai remarqué que ça ne fonctionnait pas lorsque l'on définissait d'abord la DataSource. Il faut la renseigner en dernier.

Essaye déjà ça et tiens moi au courant.

Si ça ne marche pas, il faudra que j'étudie ton code de façon plus approfondie. Pour ça, précise moi quelle ComboBox ne fonctionne pas car ta question initiale n'est pas en rapport avec ce code.

--
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
edwinzap Messages postés 149 Date d'inscription samedi 29 septembre 2012 Statut Membre Dernière intervention 21 juin 2016 2
Modifié par edwinzap le 9/04/2014 à 15:32
En tout cas merci bcp de m'aider.
Mon problème est assez complexe donc je vais le récapituler depuis le début pour plus de clarté (j'avais utiliser des noms différents aux tout début en espérant que mon problème serait plus compréhensible)
Le but de mon programme est d'enregistrer des textes de chants.
Pour le remplissage des infos du chant ainsi que les paroles, je n'ai pas de problème (pour l'instant). Je voudrais pouvoir filtrer les chants par la suite par "répertoires" ou catégories si l'on veut.
J'ai donc ajouter une combobox_repertoires. L'utilisateur peut ajouter ou supprimé des éléments de cette combobox grâce à 2 boutons. A ce niveau, j'ai déjà un problème. En effet, je voudrais directement faire les modifications dans la table "T_répertoires" de ma base de donnée.
Voici mon code:
    Private Sub ToolStripButton_RépertoireAjouter_Click(sender As Object, e As EventArgs) Handles ToolStripButton_RépertoireAjouter.Click
        Try
            Dim répertoire As String = InputBox("Nom du répertoire:", "Ajouter un nouveau répertoire").ToString
            If répertoire <> "" Then
                Dim row As DataRow = ds.Tables("T_Répertoires").NewRow
                row("Répertoire") = répertoire
                ds.Tables("T_répertoires").Rows.Add(row)

                Dim cb_repertoire As New OleDbCommandBuilder(da_repertoires)
                da_repertoires.Update(ds, "T_répertoires")

            End If
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try


Lorsque l'utilisateur choisi un répertoire, je voudrais que lorsqu'il appuie sur le bouton enregistrer après qu'il ait rempli toutes les données ainsi que les paroles, le répertoire sélectionner par la combobox soit enregistrer comme étant le répertoire du chant.

Mon problème c'est que l'utilisation des bindingsource n'est pas encore très claire pour moi. Je n'arrive pas à faire en sorte que le champ "répertoire" de la table T_chant soit rempli automatiquement avec le numéro auto de la T_répertoires.
(Alors que cela se fait automatiquement avec les paroles)
(pour pouvoir récupéré le numéro auto de la table access, je vidait mon dataset et le remplissais à nouveau avec les données de la table, mais je ne sais pas le faire pour les répertoires car toutes les données mises jusque là dans les différentes textboxes sont supprimées)

PS: je commence à me rendre compte que être autodidacte a ses limites. Je devrais commencer des études en informatique l'année prochaine.
0
Cricri1670 Messages postés 32 Date d'inscription samedi 15 décembre 2007 Statut Membre Dernière intervention 10 avril 2014
9 avril 2014 à 21:34
Bon, y'a beaucoup de choses qui peuvent bloquer.

As-tu déjà essayé de définir la propriété DataSource en dernier comme demandé ?

Ensuite, lorsque tu saisis des données relationnelles, il faut définir en premier les données parentes avant de définir les enfants. Dans ton cas, il faut donc que tu enregistres le nouveau répertoire AVANT d'enregistrer le nouveau chant.

En plus, tu utilises un numéro auto dans ta table T_Répertoires, ce qui complique un peu plus. Ce numéro sera attribué par ton moteur de base comme tu l'as sans doute compris. Ce qui veut dire qu'il faut faire attention, lors de la définition d'un nouveau répertoire, à ne pas l'attribuer puis à rafraichir la table de ton DataSet. Tu peux aussi interroger avec une commande SQL simple ta base pour récupérer le numéro attribué afin de l'enregistrer correctement dans T_chants (ce qui ne peut pas se faire automatiquement...).

Pour le Binding, n'oublie pas que les ComboBox ont deux propriétés de Binding : DisplayMember pour l'affichage et ValueMember pour la valeur. A toi de jouer avec !

La gestion des données sous .Net est très puissante mais forcément pas facile à appréhender. Il faut passer du temps à lire et relire des ouvrages sur le sujet pour bien comprendre. Je te suggère (même si je vais me faire engueuler parce hébergé par un autre site) d'aller jeter un oeil ici : http://bidou.developpez.com/
Tu y trouveras des PDF gratuits très complets sur le sujet. Tu comprendras que je ne peux écrire le code à ta place et que ce n'est qu'en acquérant les connaissances que tu y arriveras.

Commence par ce que je t'ai déjà conseillé et lis ces PDF.
Bon courage.

--
0
edwinzap Messages postés 149 Date d'inscription samedi 29 septembre 2012 Statut Membre Dernière intervention 21 juin 2016 2
9 avril 2014 à 22:32
Merci beaucoup !!!
Je vais lire tout ça et je vous tiens au courant de l'évolution le plus vite possible
Encore merci !
0
edwinzap Messages postés 149 Date d'inscription samedi 29 septembre 2012 Statut Membre Dernière intervention 21 juin 2016 2
10 avril 2014 à 12:53
J'ai essayé d'inverser datasource et datamember comme demandé et ça ne change rien pour l'instant.

"Dans ton cas, il faut donc que tu enregistres le nouveau répertoire AVANT d'enregistrer le nouveau chant"

Ce n'est pas possible de le faire dans mon cas. Je vous explique le fonctionnement du programme. Lorsque l'utilisateur clique sur nouveau, j'ajoute un enregistrement dans le datasource avec ce code:
 Dim titre As String = InputBox("Titre du chant:", "Titre")
            If titre = "" Then
                Mode_Lecture()
            ElseIf Chant_BindingSource.Find("titre", titre) >= 0 Then
                Select Case MsgBox("Le chant '" & titre & "' existe déjà !" & vbNewLine & "Voulez-vous le modifier?", MsgBoxStyle.YesNo + MsgBoxStyle.Question, "Nouveau chant")
                    Case MsgBoxResult.Yes
                        Chant_BindingSource.Position = Chant_BindingSource.Find("Titre", titre)
                        ToolStripButton_Modifier.PerformClick()
                    Case MsgBoxResult.No
                        Mode_Lecture()
                End Select
            Else

                Chant_BindingSource.AddNew()

                TextBox_Titre.Text = titre

                Chant_BindingSource.EndEdit()

                Dim cb_chant As New OleDbCommandBuilder(da_chant)

                da_chant.Update(ds, "T_chant")
                ds.Clear()
                da_chant.Fill(ds, "T_chant")
                da_paroles.Fill(ds, "T_paroles")
                da_repertoires.Fill(ds, "T_répertoires")

                Chant_BindingSource.MoveLast()

            End If

Comme vous pouvez le voir, dès que l'utilisateur a entré un nom de chant, j'enregistre le nouveau chant dans ma table. Ainsi, en rechargeant mon dataset, j'ai le numéro auto de la table. C'est la seul solution que j'ai trouvé pour l'instant. De cette manière, les num nécessaires pour lier la T_chant et T_paroles se remplissent automatiquement. L'utilisateur sélectionne APRES le répertoire et peut en ajouter/supprimer.

"Tu peux aussi interroger avec une commande SQL simple ta base pour récupérer le numéro attribué afin de l'enregistrer correctement dans T_chants (ce qui ne peut pas se faire automatiquement...)."

Cela signifie t-il qu'il est possible de récupérer le num auto sans devoir ajouter un enregistrement à la base de donnée???
Comment faire cela?
0
Cricri1670 Messages postés 32 Date d'inscription samedi 15 décembre 2007 Statut Membre Dernière intervention 10 avril 2014
10 avril 2014 à 16:28
L'approche du problème ne te permettra pas d'avoir une solution...
Je me permets d'insister : le champ numéro auto est incrémenté par le moteur de la base de données à la création d'un enregistrement. Il n'y a qu'en rechargeant la table de ton dataset ou en interrogeant la base avec une requête action que tu pourras le récupérer. De plus, lors de données relationnelles, si le code répertoire de la table chants est à saisie obligatoire, tu dois d'abord créer l'enregistrement parent avant l'enfant, c'est normal ! Si c'est un champ qui accepte Null ou vide, tu peux le renseigner plus tard.

Perso, je pense qu'il faut que tu décortiques ton problème en essayant de gérer d'abord le problème Répertoire avant de gérer le problème Chant.

Lis les PDF, tu y apprendra beaucoup de choses et garde la définition DataSource en dernier, ça ne mange pas de pain.
0
Rejoignez-nous