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

Windows Forms Discussion :

Tri multiple sur un DataTable et garder uniquement les lignes distinctes


Sujet :

Windows Forms

  1. #1
    Membre régulier Avatar de Chacha35
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    264
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2009
    Messages : 264
    Points : 114
    Points
    114
    Par défaut Tri multiple sur un DataTable et garder uniquement les lignes distinctes
    Bonjour,

    Je cherche un moyen pour garder uniquement dans mon DataTable les lignes distinctes par rapport à certains champs.

    J'ai cherché et j'ai trouvé un truc qui marche, mais qui ne regarde qu'un champ.

    Il commence par trier la DataTable avec le champ, en parcourant les lignes puis il regarde si ce champ de la ligne précedente est égal à celui de la ligne en cours : si non il ajoute la ligne dans une table.

    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
     
            public DataTable SelectDistinct(DataTable TableSource, DataTable TableRetour, string NomChamps)
            {
                object LastValue = null;
                    foreach (DataRow dr in TableSource.Select("", NomChamps))
                    {
                        if (LastValue == null || !(DataColumn.Equals(LastValue, dr[NomChamps])))
                        {
                            LastValue = dr[NomChamps];
                            TableRetour.ImportRow(dr);
                        }
                    }
     
                return TableRetour;
            }
    Mais mon soucis c'est que je voudrais supprimer les lignes lorsqu'elles ont les deux premiers champs en commun.

    Il faut donc que je trie ma DataTable par le premier champ mais aussi après par le deuxième.

    Sauf qu'on ne peut pas faire ça dans un DataTable.Select.

    J'ai trouvé qu'on pouvais faire un tri multiple avec un DataView, mais après je ne sais pas comment reremplir ma DataTable avec ce DataView.


    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
     
            public DataTable SelectDistinct(DataTable TableSource, DataTable TableRetour, string NomChamps1, string NomChamps2)
            {
                    DataView dv = new DataView(MaTableObjet);
                    dv.RowFilter = "'" + NomChamps1 + "' ASC, '"+NomChamps2+"' ASC";
                    // Remplir TableSource avec dv
                    object LastValue1 = null;
                    object LastValue2 = null;
                    foreach (DataRow dr in TableSource.Rows)
                    {
                        if (LastValue == null || !(DataColumn.Equals(LastValue1, dr[NomChamps1])) && !(DataColumn.Equals(LastValue2, dr[NomChamps2])))
                        {
                            LastValue1 = dr[NomChamps1];
                            LastValue2 = dr[NomChamps2];
                            TableRetour.ImportRow(dr);
                        }
                    }
                return TableRetour;
            }
    Si vous avez une autre idée pour garder uniquement les lignes distinctes pour les 2 premiers champs, je suis aussi prenneuse.

    Merci d'avance

  2. #2
    Membre émérite
    Avatar de laedit
    Homme Profil pro
    Consultant études et développement
    Inscrit en
    Décembre 2006
    Messages
    1 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant études et développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 344
    Points : 2 265
    Points
    2 265
    Par défaut
    Le mieux étant de le faire à la main.

    Tu parcours ta table, vérifie et compare les valeurs, et sélectionne les lignes que tu veux garder en les mettant dans une autre lignes.

    Faut savoir se mouiller des fois
    Blog - Articles - Framework

    MSDN vous aide, si si, alors n'hésitez pas à y faire un tour avant de poser une question.
    Ah, et n'oubliez pas, Google peut répondre à la majorité de vos questions.

  3. #3
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Je pense qu'a partir de 3.5 il y a des Methodes Linq qui peuvent faire le distinct
    « Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)

  4. #4
    Membre régulier Avatar de Chacha35
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    264
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2009
    Messages : 264
    Points : 114
    Points
    114
    Par défaut
    J'ai trouvé ça pour le linq mais c'est un distinct sur un seul champ.
    Je n'ai pas trouvé pour 2 champs.

    j'ai une solution mais ce n'est vraiment pas optimisé car je parcours 2 fois ma table. Je trie pour le 2ème champs et après pour le 1er.

    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
     
    public DataTable SelectDistinct(DataTable TableSource, DataTable TableRetour, string NomChamps1, string NomChamps2)
            {
     
                    DataTable TableRetourBis = new DataTable();
                    TableRetourBis = TableRetour.Clone();
                    object LastValue1 = null;
                    object LastValue2 = null;
                    foreach (DataRow dr in TableSource.Select("", NomChamps2))
                    {
                        TableRetourBis.ImportRow(dr);
                    }
                    foreach (DataRow dr in TableRetourBis.Select("", NomChamps1))
                    {
                        if (LastValue1 == null || (!(DataColumn.Equals(LastValue1, dr[NomChamps1])) && !(DataColumn.Equals(LastValue2, dr[NomChamps2]))))
                        {
                            LastValue1 = dr[NomChamps1];
                            LastValue2 = dr[NomChamps2];
                            TableRetour.ImportRow(dr);
                        }
                    }
                return TableRetour;
            }
    Si vous avez mieux...

  5. #5
    Membre émérite
    Avatar de laedit
    Homme Profil pro
    Consultant études et développement
    Inscrit en
    Décembre 2006
    Messages
    1 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant études et développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 344
    Points : 2 265
    Points
    2 265
    Par défaut
    Euh, là, ça sert à quoi de faire des order by ?

    Tu pourrais toujours récupérer en premier lieu les lignes qui t'intéressent et ensuite les ordonner, non ?

    Parce que là, si j'ai bien vu, dans la première boucle tu ajoute toutes les lignes résultantes du tri, puis ensuite tu reparcours cette table dans un autre sens de tri et à qui tu applique des tests...

    Je pense qu'en ne conservant que la deuxième boucle tu devrais arriver au même résultat.
    Blog - Articles - Framework

    MSDN vous aide, si si, alors n'hésitez pas à y faire un tour avant de poser une question.
    Ah, et n'oubliez pas, Google peut répondre à la majorité de vos questions.

  6. #6
    Membre régulier Avatar de Chacha35
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    264
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2009
    Messages : 264
    Points : 114
    Points
    114
    Par défaut
    Et bien non en faite;

    Car je souhaite trouver les lignes distinctes en fonction des 2 premiers champs de ma Table.

    Je parcoure les lignes et je compare avec celle d'avant.

    Exemple de table :

    champ1 - champ2
    2 - 3
    3 - 1
    1 - 1
    1 - 3
    2 - 1
    2 - 2
    1 - 2
    1 - 1

    Si je trie seulement avec le premier champs :

    1 - 1
    1 - 3
    1 - 2
    1 - 1
    2 - 3
    2 - 1
    2 - 2
    3 - 1

    Si je trie seulement avec le deuxieme champs :

    3 - 1
    1 - 1
    2 - 1
    1 - 1
    2 - 2
    1 - 2
    2 - 3

    Et bien comme je compare une ligne avec la précédente j'aurai 2 fois : 1 - 1

    Alors que si je trie sur le 2ème puis sur le premier j'enleverai cette ligne.

    1 - 1
    1 - 1
    1 - 2
    2 - 1
    2 - 2
    2 - 3
    3 - 1

    Je voulais tout trier d'un coup mais je n'ai pas réussie.
    Mon but n'est pas d'ordonner les lignes mais de supprimer les doublons.

  7. #7
    Membre émérite
    Avatar de laedit
    Homme Profil pro
    Consultant études et développement
    Inscrit en
    Décembre 2006
    Messages
    1 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant études et développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 344
    Points : 2 265
    Points
    2 265
    Par défaut
    Et tu ne peux pas préciser les deux champs directement dans le select ?

    Sinon ça serait limite plus rapide de faire appel directement à la base de données :p
    Blog - Articles - Framework

    MSDN vous aide, si si, alors n'hésitez pas à y faire un tour avant de poser une question.
    Ah, et n'oubliez pas, Google peut répondre à la majorité de vos questions.

  8. #8
    Membre régulier Avatar de Chacha35
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    264
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2009
    Messages : 264
    Points : 114
    Points
    114
    Par défaut
    Dans la doc de msdn, j'ai pas vu qu'on pouvais faire un double tri avec un select.

    Et DISTINCT en SQL ne prend pas d'argument, il compare la ligne en entier.

    Je vais poser la question dans le forum sql server, pour selectionner les lignes qui n'ont pas les 2 premiers champs identiques, car je n'ai pas trouvé grand chose sur le net.

  9. #9
    Membre actif Avatar de AJemni
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2008
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2008
    Messages : 242
    Points : 290
    Points
    290
    Par défaut
    Bonjour,
    juste une idée : utilise le DefaultView c'est plus pratique et simplifie enormement ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tableSource.DefaultView.Sort = "Col1, Col2 Desc";
    tableSource.DefaultView.RowFilter = "Col1 = 'Le filtre'";
    tableRetour = tableSource.DefaultView.ToTable();
    A+

  10. #10
    Membre régulier Avatar de Chacha35
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    264
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2009
    Messages : 264
    Points : 114
    Points
    114
    Par défaut
    AJemni, ta solution permet le trie, mais pas la suppression des doublons.
    Merci comme même

    Sinon pour la requête sql, c'est tout simple en fait.

    Comme je n'ai besoin que des champs sur lesquels je fais le distinct, ça marche très bien, mais bon ça me fais charger encore une autre table:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT DISTINCT colonne1,colonne2
    FROM table
    PS: Merci aux potes du forum sql server !

    Plus j'apprend des trucs et plus je cherche compliqué!

  11. #11
    Nouveau membre du Club
    Profil pro
    Ostéopathe
    Inscrit en
    Juillet 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ostéopathe

    Informations forums :
    Inscription : Juillet 2010
    Messages : 26
    Points : 37
    Points
    37
    Par défaut
    Bonjour

    Sous visual studio 2008 (et peut être dans les versions antérieures) la fonction select d'un datatable accepte deux arguments, chacun étant une string.

    Donc pour répondre à la question initiale de ce sujet, pour trier un datatable sur plusieurs colonnes il faut utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonDatatable.Select(Nothing, "NomColonneDeTri1, NomColonneDeTri2")
    Comme en SQL il est possible de préciser le sens du tri avec ASC et DESC (par défaut le tri est ASC)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonDatatable.Select(Nothing, "NomColonneDeTri1 DESC, NomColonneDeTri2 ASC")
    Pour filtrer les lignes selon une condition il suffit de remplacer Nothing par la condition que l'on veut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonDatatable.Select("(NomColonneCondition1 = 'Condition1' OR NomColonneCondition1 = 'Condition01') AND NomColonneCondition2 = 'Condition2'", "NomColonneDeTri1 DESC, NomColonneDeTri2 ASC")
    En espérant que ça serve

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

Discussions similaires

  1. [XL-2003] Garder uniquement les valeurs des cellules avec PasteSpecial et With Worksheets
    Par tibs1502 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 06/02/2013, 14h57
  2. Réponses: 2
    Dernier message: 17/10/2012, 08h53
  3. garder uniquement les chiffres après la ,
    Par bob737 dans le forum Langage
    Réponses: 4
    Dernier message: 28/11/2011, 14h04
  4. tri multiple sur array()
    Par proxichou dans le forum Langage
    Réponses: 2
    Dernier message: 02/11/2010, 14h24
  5. Tris multiples sur Objets
    Par gudul dans le forum Langage
    Réponses: 2
    Dernier message: 04/12/2007, 19h47

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