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

C# Discussion :

Comparer deux cases dans deux tables Access


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2016
    Messages : 4
    Par défaut Comparer deux cases dans deux tables Access
    Bonjour,

    J'essaye de développer un programme pour une association étudiante. Le but est d'affecter des filleuls à des parrains. Alors je tiens à préciser que je n'ai jamais eu de cours de programmation et que mon vocabulaire est assez limité lui aussi.

    J'ai déjà fait les Form, tout marche niveau interface.

    Pour l'affectation, J'ai 4 critères qui donnent des points s'ils sont en commun. J'ai donc deux tables dans une base de donnée access et je voudrais comparer par exemple :
    - la colonne 4 de la ligne i de la table parrain
    avec
    - la colonne 4 de la ligne j de la table filleul

    Mais je ne sais pas comment dire au programme d'aller chercher ces deux valeur.
    Pour info, les bases de données sont déjà chargé dans le programme (ils sont visibles dans des Data Grid View)

    Voici un exemple de ce que je veux faire :

    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
     
            static void Affectations(int nombreDeParrain, int nombreDeFilleul)
            {
                // dire au programme d'aller compter le nombre de parrain et le nombre de filleul
                for (int i = 0; i < nombreDeParrain; i++)
                {
                    //Pour chaque parrain "i", faire :
     
                    for (int j = 0; j < nombreDeFilleul; j++)
                    {
                        int Case44;
                        int Case55;
                        int Case88;
                        int Case99;
                        int score;
     
                        if (//case 4 du parrain i = Case 4 du Filleul j)
                        {
                            Case44 = Program.parametre.Par_Coef_Ecole;
                        }
                        else
                        {
                            Case44 = 0;
                            //Enregistrer la case 44 dans la base de donnée affectation
                        }
    Dans ma class AccesDonnees j'ai cela :

    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
            public static DataTable ChargerParrain()
            {
                DataTable dtParrain = new DataTable();
     
                string strSQL =
                "SELECT Table_Parrains.P_Numero as [Numéro], Table_Parrains.P_Nom as Nom, Table_Parrains.P_Prenom as [Prénom], Table_Parrains.P_Ecole as [Ecole], Table_Parrains.P_Genre as Genre, Table_Parrains.P_Langue_1 as [Langue 1], Table_Parrains.P_Langue_2 as [Langue 2], Table_Parrains.P_Langue_3 as [Langue 3], Table_Parrains.P_Nationalite as [Nationalité] FROM Table_Parrains";
                OleDbDataAdapter daProbleme = new OleDbDataAdapter(strSQL, Program.connexionBDEtudiants);
     
                daProbleme.Fill(dtParrain);
     
                return dtParrain;
            }
            public static DataTable ChargerFilleul()
            {
                DataTable dtFilleul = new DataTable();
     
                string strSQL =
                "SELECT Table_Filleuls.F_Numero as [Numéro], Table_Filleuls.F_Nom as Nom, Table_Filleuls.F_Prenom as [Prénom], Table_Filleuls.F_Ecole as [Ecole], Table_Filleuls.F_Genre as [Genre], Table_Filleuls.F_Langue_1 as [Langue 1], Table_Filleuls.F_Langue_2 as [Langue 2], Table_Filleuls.F_Langue_3 as [Langue 3], Table_Filleuls.F_Nationalite as [Nationalité]FROM Table_Filleuls";
                OleDbDataAdapter daProbleme = new OleDbDataAdapter(strSQL, Program.connexionBDEtudiants);
     
                daProbleme.Fill(dtFilleul);
     
                return dtFilleul;
            }


    Je suis conscient que ce n'est pas un code très efficient, mais avec mes connaissances très limité, il est difficile pour moi de faire mieux. Donc si vous pouvez m'aider à comparer ces deux valeurs.

    Si vous avez besoin d'informations supplémentaires, n'hésitez pas à me demander.

    Bonne journée.

  2. #2
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    Salut,

    Chaque ligne d'une DataTable s'appelle un DataRow. Et chaque DataRow contient des cellules qui sont accessible via leur colonne (soit l'index de base 0 de la colonne, soit son nom). C'est cela que tu vas comparer.

    Tu devrais faire qqch dans le genre
    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
    private void comparaison()
        {
            DataTable dtParrains = ChargerParrain();
            DataTable dtFilleuls = ChargerFilleul();
     
     
            foreach (DataRow drParrain in dtParrains.Rows)
            {
                int scoreMax = 0;
                int indexMeilleurFilleur = -1;
                for (int i=0; i < dtFilleuls.Rows.Count - 1; i++)
                {
                    DataRow drFilleul = dtFilleuls.Rows[i];
                    int intEcole = 0;
                    int intLangue = 0;
                    int intNationalite = 0;
                    int scoreFilleul = 0;
                    if (drParrain["Ecole"].Equals(drFilleul["Ecole"]))
                        intEcole = 4;   //admettons que l'école soit très importante, donc on lui donne bcp de points
                    if (drParrain["Langue 1"].Equals(drFilleul["Langue 1"]))
                        intLangue = 3;   //admettons que la langue soit un peut moins importante que l'école, donc on lui donne un peu moins de points
                    if (drParrain["Nationalité"].Equals(drFilleul["Nationalité"]))
                        intLangue = 1;   //admettons que la nationalité soit le moins important, donc on lui donne le moins de points
                    scoreFilleul = intEcole + intLangue + intNationalite;
                    if (scoreFilleul > scoreMax)
                    {
                        scoreMax = scoreFilleul;
                        indexMeilleurFilleur = i;
                    }
                }
            }
        }
    Petite remarque : évite les espaces et les accents dans les noms. Il vaut mieux remplacer "Langue 1" par Langue1 et Nationalité par Nationalite

    Tu remarqueras aussi que j'ai instancié scoreMax et indexMeilleurFilleur au niveau du parrain, parce que si on compare les filleuls, il est intéressant de se souvenir lequel est le meilleur.
    Pourquoi avoir instancié indexMeilleurFilleur à -1 ? Comme l'index d'une table démarre à 0, il est commun de considérer que si on a -1 c'est qu'aucun index n'est sélectionné.
    Enfin, je ne sais pas si ça a de l'importance, mais j'imagine que si un filleul a déjà un parrain, il n'est pas nécessaire de le retester. Pour cela tu pourrais ajouter une colonne dans la table des filleuls et y mettre un identifiant unique du parrain (je n'ai pas vu de clé primaire dans des tables, c'est pour cela que j'ai utilisé les index. Mais il est important d'avoir une clé unique dans chaque table, parce qu'il peut y avoir 2 parrains qui ont le même nom, et 2 filleuls aussi. Donc un ID_Parrain et un ID_Filleul me semblent utiles).
    Ainsi, lorsque le meilleur filleul a été trouvé pour un parrain, tu pourrais mettre l'ID_Parrain dans la colonne Parrain de la table dtFilleuls.
    Comme un filleul qui a déjà un parrain n'y a plus besoin de tester ce filleul et on passer au suivant.
    Évidemment, tu peux inverser et rechercher le meilleur parrain pour chaque filleul. Mais l'accès aux données des lignes et des colonnes des DataTable reste le même.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2016
    Messages : 4
    Par défaut
    Bonjour Jean-Marc68,

    Tout d'abord, merci beaucoup pour l'aide que tu m'as apporté. Il y a plein de chose de base comme ça que je ne sais pas et ça ne me rends pas la tâche facile..

    J'ai repris ton code et je l'ai un peu adapté, le voici :

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    private void comparaison()
            {
                AccesDonnees.ChargerParrain();
                AccesDonnees.ChargerFilleul();
     
                //Pour chaque combinaison Parrain/Filleul, on veut comparer les valeurs des cases Ecole, Genre et Nationalite.
                //De plus, on veut aussi comparer les valeurs des cases Langue 1, Langue 2 et langue 3 entre elles
                //Le score total est enregistré dans la table affectation avec P_Numero, F_Numero, A_Score et Choix
                foreach (DataRow drParrain in Program.dtParrain.Rows)
                {
                    for (int i = 0; i < Program.dtFilleul.Rows.Count - 1; i++)
                    {
                        DataRow drFilleul = Program.dtFilleul.Rows[i];
                        int intEcole = 0;
                        int intGenre = 0;
                        int intNationalite = 0;
                        int scoreParrainFilleul = 0;
                        int intLangue11 = 0;
                        int intLangue12 = 0;
                        int intLangue13 = 0;
                        int intLangue21 = 0;
                        int intLangue22 = 0;
                        int intLangue23 = 0;
                        int intLangue31 = 0;
                        int intLangue32 = 0;
                        int intLangue33 = 0;
     
                        if (drParrain["Ecole"].Equals(drFilleul["Ecole"]))
                            intEcole = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Genre"].Equals(drFilleul["Genre"]))
                            intGenre = Program.parametre.Par_Coef_Genre;
                        if (drParrain["Nationalité"].Equals(drFilleul["Nationalité"]))
                            intNationalite = Program.parametre.Par_Coef_Nationalite;
                        if (drParrain["Langue 1"].Equals(drFilleul["Langue 1"]))
                            intLangue11 = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Langue 1"].Equals(drFilleul["Langue 2"]))
                            intLangue12 = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Langue 1"].Equals(drFilleul["Langue 3"]))
                            intLangue13 = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Langue 2"].Equals(drFilleul["Langue 1"]))
                            intLangue21 = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Langue 2"].Equals(drFilleul["Langue 2"]))
                            intLangue22 = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Langue 2"].Equals(drFilleul["Langue 3"]))
                            intLangue23 = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Langue 3"].Equals(drFilleul["Langue 1"]))
                            intLangue31 = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Langue 3"].Equals(drFilleul["Langue 2"]))
                            intLangue32 = Program.parametre.Par_Coef_Ecole;
                        if (drParrain["Langue 3"].Equals(drFilleul["Langue 3"]))
                            intLangue33 = Program.parametre.Par_Coef_Ecole;
     
     
                        scoreParrainFilleul = intEcole + intGenre + intNationalite + intLangue11 + intLangue12 + intLangue13 + intLangue21 + intLangue22 + intLangue23 + intLangue31 + intLangue32 + intLangue33;
     
                        // Sauvegarde du score de l'association du parrain i avec le filleul j 
                        // On dit ou aller chercher les information à enregistrer
                        Program.affectation.P_Numero = Convert.ToString(???); //Quelle variable mettre ?
                        Program.affectation.F_Numero = Convert.ToString(???); //Quelle variable mettre ?                    
                        Program.affectation.A_Numero = "A_" + Program.affectation.P_Numero +"_"+ Program.affectation.F_Numero;
                        Program.affectation.A_Score = scoreParrainFilleul;
                        Program.affectation.Choix = false;
     
                        // On enregistre les informations dans la base de donnée (Table_Affectations)
                        AccesDonnees.EnregistrerAffectation();
     
                    }
                }
            }
    Comme tu le vois, j'ai enlevé le scoremax car en faite, je veux sauvegarder toutes les solutions dans une base de donnée. Donc tous les parrains auront un score avec tous les filleuls (même si c'est 0).

    Je voulais morceler le problème comme cela :
    1 - Créer une table avec toutes les combinaison Parrain/Filleul avec leurs score
    2 - Trier cette table par la colonne A_Score en ordre décroissant
    3 - Prendre les meilleurs valeur et les affecter (en respectant les contrainte qui sont : 1 parrain par filleul et entre 3 et 4 filleul par parrain)

    Pour le code que tu m'as écris, j'ai rajouté une colonne Choix (booléenne) que je mets automatiquement à false.
    J'ai rajouté également d'autres comparaisons entres les langues. Encore une fois ce n'est pas optimal mais bon..

    Dans chacune de mes tables il y a une clé: pour Table_Parrain: c'est "P_Numero", pour Table_Filleul : c'est "F_Numero", pour Table_Affectation c'est :"A_Numero". Je sais que pour cette dernière j'aurais pu utiliser une clé composé, mais je vais rester dans le simple

    Mes clés sont dans le format "P001" soit du string. Donc je cherche à ce que la boucle recherche "P001" et "F001" et qu'ensuite il cherche la colonne en question. De plus, dans l'enregistrement, j'ai mis des "???" pour l'enregistrement de ces ID. Tu saurais comment je pourrais lui dire de mettre le P_Numero et le F_Numero de la boucle dans laquelle on est ?

    Encore une fois, merci pour ton aide !

    Bonne journée.

  4. #4
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    AccesDonnees.ChargerParrain();
    AccesDonnees.ChargerFilleul();
    Si je ne me trompe pas, tes méthodes ChargerQQC retournent des datatables. Il faut donc qu'elles implémentent des tables (qu'elles mettent les données quelque part).
    Il te faut donc qqch du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DataTable dtParrains = AccesDonnees.ChargerParrain();
    DataTable dtFilleuls = AccesDonnees.ChargerFilleul();
    Pour le résultat, je créerais une Table dans la base de données de départ. Cette table contiendrait les champs P_Numero, F_Numero et Score.
    J'y modifierais aussi les valeurs des identifiants P_Numero et F_Numero en y stockant des int au lieu de textes. C'est plus facile à classer et à rechercher et il n'est pas nécessaire de mettre P001 dans la colonne P_Numéro. Si il y a un numéro dans cette colonne, c'est forcément le numéro d'un parrain. Donc le P est superflu. Idem pour le F des filleuls.

    Une fois la table de résultats créée dans la mdb de départ, tu la charge comme les autres (même si elle est vide, la charger par un Fill te permet de charger son schéma. et va te permettre de lui faire un update pour lui retourner les valeurs des résultats).
    Mais avant de retourner le résultat, quand tu as calculé un résultat entre un parrain et un filleul, tu alimente la table dtResultat comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                DataRow drNouveauResultat = dtResultat.NewRow();        //création d'une nouvelle ligne du même type que la table dtResultat
                drNouveauResultat["P_Numero"] = drParrain["P_Numero"];  //mettre les valeurs dans les champs de la nouvelle ligne
                drNouveauResultate["P_Filleul"] = drParrain["P_Filleul"];
                drNouveauResultat["Score"] = intScore;
                dtResultat.Rows.Add(drNouveauResultat);                 //ajouter la nouvelle ligne dans la table

    À la fin, tu fais un insert des nouvelles lignes de ta datatable
    dtResultat vers ta base de données et le tour est joué.
    Si besoin, pour le insert tu trouveras toute l'info ici : msdn.microsoft.com/en-us/library/system.data.oledb.oledbdataadapter.insertcommand(v=vs.110).aspx

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2016
    Messages : 4
    Par défaut
    J'ai modifié les clés et les ai toutes mit en int comme tu me l'a suggéré.


    Alors oui, désolé, je n'ai pas mis tous les codes, ça serait bien trop long sinon. Mes BD ont été chargé dans le program.cs :

    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
            public const string strAccessBDEtudiants = @"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = BD-Etudiants.accdb";
            public static OleDbConnection connexionBDEtudiants;
            public static DataTable dtParrain;
            public static DataTable dtFilleul;
            public static DataTable dtAffectation;
     
                connexionBDEtudiants = new OleDbConnection(strAccessBDEtudiants);
                connexionBDEtudiants.Open(); // le .close() a été mit a la sortie du programme
     
            static void Main()
            {
                dtParrain = AccesDonnees.ChargerParrain();
                dtFilleul = AccesDonnees.ChargerFilleul();
                dtAffectation = AccesDonnees.ChargerAffectation(); //c'est la table ou les résultats seront sauvegardés
     
    ...
    En reprenant ton code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
                        // Création d'une nouvelle ligne du même type que la table dtAffectation
                        DataRow drNouveauResultat = Program.dtAffectation.NewRow();
                        // Mettre les valeurs dans les champs de la nouvelle ligne
                        drNouveauResultat["A_Numero"] = drParrain["P_Numero"+"P_Filleul"];
                        drNouveauResultat["P_Numero"] = drParrain["P_Numero"];  
                        drNouveauResultat["P_Filleul"] = drParrain["P_Filleul"];
                        drNouveauResultat["A_Score"] = scoreParrainFilleul;
                        drNouveauResultat["Choix"] = false;
     
                        // Ajouter la nouvelle ligne dans la table
                        Program.dtAffectation.Rows.Add(drNouveauResultat);
     
                        // On enregistre les informations dans la base de donnée (Table_Affectations)
                        AccesDonnees.EnregistrerAffectation();


    Et en ayant dans mon AccesDonnees.cs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
            public static void EnregistrerAffectation()
            {
     
                //Commencer par ajouter un nouvel enregistrement à la table affectation
                string strSQL = "INSERT INTO Table_Affectations ([A_Numero], [P_Numero], [F_Numero], [A_Score], [Choix],) values (\"" +
                    Program.affectation.A_Numero + "\",\"" + Program.affectation.P_Numero + "\",\"" + Program.affectation.F_Numero + "\"," + Program.affectation.A_Score.ToString() + Program.affectation.Choix + ",)";
                OleDbCommand insererSolution = new OleDbCommand(strSQL, Program.connexionBDEtudiants);
                insererSolution.ExecuteNonQuery();
     
            }
    Est-ce qu'il n'y aura pas un problème entre le :"Program.dtAffectation.Rows.Add(drNouveauResultat);" et le INSERT INTO ? Est-ce que le INSERT INTO va bien prendre les valeurs enregistrer avant ?
    Malheureusement je ne peux pas encore vérifier, j'ai un autre problème avec la base de donnée qui efface les modifications que je fais quand je lance le programme. Je règle ça et je te tiens au courant.

    Merci encore

  6. #6
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    Il faut que tu crées des paramètres dans ton insert pour ne pas devoir "t'amuser" à faire tes insert ligne par ligne.
    Relis bien la page msdn.microsoft.com/en-us/library/system.data.oledb.oledbdataadapter.insertcommand(v=vs.110).aspx, il y a des exemples.

Discussions similaires

  1. Comparer deux listes dans deux tables
    Par djongar dans le forum Langage SQL
    Réponses: 7
    Dernier message: 18/01/2012, 15h36
  2. [AC-2003] Comparer deux champs dans une table et remplir un autre champ
    Par frexville dans le forum VBA Access
    Réponses: 3
    Dernier message: 07/09/2009, 12h52
  3. calcul entre deux champs dans une table
    Par pomar dans le forum Access
    Réponses: 7
    Dernier message: 29/11/2006, 18h27
  4. Comparaison entre deux dates dans une table
    Par Biskot75 dans le forum Access
    Réponses: 6
    Dernier message: 19/09/2006, 11h16
  5. Lier deux champs dans deux tables ?
    Par Olivierc dans le forum Access
    Réponses: 3
    Dernier message: 28/04/2006, 23h13

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