C# trier une colonne d'un DataGridView à l'aide d'une listBox

Fermé
Melman - 28 juil. 2020 à 08:59
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 - 21 août 2020 à 21:32
Bonjour,
je souhaiterai trier une colonne d'une datagridview en fonction de son contenu, ce qu'il me faudrait en particulier c'est le fait que la listbox détecte les différentes possibilités et me les affiches puis laisse apparaître le contenu du datagridview en fonction de la listbox



Configuration: Windows / Chrome 84.0.4147.89
A voir également:

16 réponses

Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
28 juil. 2020 à 10:39
Bonjour

Comment est alimenté le datagridview?
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
28 juil. 2020 à 11:20
Bonjour whismeril, j'ai déja eu affaire à ton aide (je reviens à peine sur mon projet), tu m'avais fournis un exemple qui me permettais de filtrer une colonne grâce à la listbox en question.

Mon datagridview est remplis à l'aide d'une list remplis au préalable par une classe qui parse mes logs

voici l'exemple
j'aimerai filtrer comme ça sur d'autre colonne pour limiter l'affichage je mettais tourner vers l'advancedDatagridview qui fournis un systèmes de filtres cependant il ne fonctionne pas
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
28 juil. 2020 à 12:18
J’ai reparcouru rapidement la discussion précédente.
As tu choisi de filtrer avant de charger les fichiers ou après ?
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
28 juil. 2020 à 13:54
J'ai choisi de filtrer après je sais si je peux filtrer avant étant donner que je ne sais pas ce que je vais récupérer
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
28 juil. 2020 à 14:06
En fait tu pourrais faire un pré traitement à partir du quel générer tes filtres.
Ça pourrait même ne pas être plus beaucoup long à l’exécution.
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
28 juil. 2020 à 14:34
C'est à dire ; (genre récupérer les éventuels filtres puis faire le traitement une fois les filtres choisis ?)
0

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

Posez votre question
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
Modifié le 28 juil. 2020 à 16:26
Finalement j'ai réussi a faire le tri avec plusieurs listbox, je réduis drastiquement l'affichage dans mon datagridview, j'aimerai savoir si une pagination en plus de ces filtres était possible (limiter à 100 lignes)et si les filtres pouvais ce combiner ?

Exemple:


On a bien Agv::Execution et N_DEFAUT (car il n'y a que lui) mais pour ce qui est de PLC_RDK et bien il ce transforme en AGVn°6
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
28 juil. 2020 à 16:29
Oui au deux questions.

Tu peux faire un traitement rapide pour récupérer les données uniques de chaque colonne qui peut filtrer et ensuite ne charger que les lignes adéquates.

Pour n’avoir que 100 lignes à chaque d’affichées, tu peux te servir des méthodes skip et take de la list<t> que tu auras par exemple remplies à l’aide d’une scrollbar
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
28 juil. 2020 à 17:16
Je ne vois pas trop comment me lancer dans un traitement rapide...

Ton option ne me permettra pas de naviguer comme un livre par exemple ?
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
28 juil. 2020 à 23:11
En repartant de ça

        private void ChargerFichier()
        {
            string[] lignes = File.ReadAllLines("LogisticCore300120.log");//chaaque ligne est chagée dans un emplacement de tableau

            foreach(string l in lignes)//on itère le tableau pour créer la liste de logs
            {
                Log leLog = Log.Parse(l);
                if (leLog != null)
                    lesLogs.Add(leLog);
                else
                    File.AppendAllText("LignesEnErreur.txt", l);//écrit les lignes rejétées dans le fichier LignesEnErreur.txt
            }

            lesLogs = lesLogs.OrderBy(x => x.Datation).ToList();
        }



J'ai fait un test vite fait.
Sur le formulaire, j'ai ajouté 2 listbox et un bouton
J'ai modifié le code au dessus:
        List<Log> lesLogs = new List<Log>();//liste de tous les logs

        string[] lignes;
        List<string> filtreModule = new List<string>();
        List<string> filtreType = new List<string>();

        private void ChargerFiltres()
        {
            lignes = File.ReadAllLines("LogisticCore300120.log");//chaque ligne est chagée dans un emplacement de tableau

            filtreModule.Clear();
            filtreType.Clear();

            foreach (string l in lignes)
            {
                string[] valeurs = l.Split('\t');//pour bien faire il faudrait utiliser la regex
                if (l.Length < 3)
                    continue;

                if (!filtreModule.Contains(valeurs[1]))
                    filtreModule.Add(valeurs[1]);

                if (!filtreType.Contains(valeurs[2]))
                    filtreType.Add(valeurs[2]);
            }
            //on peut peut-être optimiser le temps de chargement des filtres

            lstModule.DataSource = filtreModule;//listbox pour les modules
            lstType.DataSource = filtreType;//listbox pour les Types
        }

        private void ChargerFichier(string[] filtres)
        { 
            foreach (string l in lignes)//on itère le tableau pour créer la liste de logs
            {
                bool ok = true;//si ça reste ok, on garde la ligne
                foreach(string f in filtres)
                {
                    if(!l.Contains(f))
                    {
                        ok = false;
                        break;
                    }
                }

                if (!ok)
                    continue;

                Log leLog = Log.Parse(l);
                if (leLog != null)
                    lesLogs.Add(leLog);
                else
                    File.AppendAllText("LignesEnErreur.txt", l);//écrit les lignes rejétées dans le fichier LignesEnErreur.txt
            }

            lesLogs = lesLogs.OrderBy(x => x.Datation).ToList();
        }



Et pour le bouton
        private void button1_Click(object sender, EventArgs e)
        {
            ChargerFichier(new[] { lstModule.Text, lstType.Text });
            dgwLog.DataSource = null;
            dgwLog.DataSource = lesLogs;

        }


Les filtres sont un peu longs à charger, je dois pouvoir faire mieux, mais pas ce soir
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
Modifié le 29 juil. 2020 à 10:13
Je suis un peu perdu étant donné que j'ai pas mal modifier le début pour trier, je ne vois pas trop quand appeler ChargerFiltres, quand je fais chargerfichier il me remontre l'erreur suivante :


en re testant avec tes fonctions je me rends compte que ma regex n'est pas passer alors que sur le même fichier celle-ci fonctionne
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
29 juil. 2020 à 14:16
Oui, regarde à la ligne 3, j’ai mis la déclaration de lignes plus global de façon à ne le charger qu’une fois
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
30 juil. 2020 à 14:07
Ouais mais je vois pas trop quand on appel ChargerFiltres
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
30 juil. 2020 à 17:09
Là oú avant tu appelais chargerfichier
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
30 juil. 2020 à 18:51
Par contre, dans cet exemple vite fait on peut tomber sur des cas « impossibles »

C’est à dire que tu peux sélectionner une combinaison de filtres qui ne donnent aucun résultat.
C’est pas forcément cool pour l’utilisateur qui va faire des manips pour rien.

Une autre options serait de tout charger les logs comme avant mais sans les afficher dans le datagridview.
On se contente d’afficher une première liste de filtres (sur le module par exemple), avec le mot clé et le nombre d’occurrences.

L’utilisateur sélectionne un mot clé un bouton apparaît lui proposant de tout afficher et une liste montre les types vraiment présents pour le module sélectionné et le nombre d’occurrences etc...
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
31 juil. 2020 à 10:36
J'avais penser a cette possibilité du coup je m'étais dit, laisser toute les occurrences possibles mais en fonctions des combinaisons mettre 0 occurrences ou bien le nombre disponible en fonction des combinaisons
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
31 juil. 2020 à 14:26
Alors,

avec un datagridview et 2 listes
On repart avec la méthode chargerFichier d'origine

        private void ChargerFichier()
        {
            string[] lignes = File.ReadAllLines("LogisticCore300120.log");//chaaque ligne est chagée dans un emplacement de tableau

            foreach(string l in lignes)//on itère le tableau pour créer la liste de logs
            {
                Log leLog = Log.Parse(l);
                if (leLog != null)
                    lesLogs.Add(leLog);
                else
                    File.AppendAllText("LignesEnErreur.txt", l);//écrit les lignes rejétées dans le fichier LignesEnErreur.txt
            }

            lesLogs = lesLogs.OrderBy(x => x.Datation).ToList();
        }


et on reprend la class logGroupe, avec un constructeur supplémentaire et un ToString personnalisé

    /// <summary>
    /// Enregsitre les regroupements de logs correspondant à un filtre
    /// </summary>
    class LogGroupe
    {
        public LogGroupe(string Cle, List<Log> LesLogs)
        {
            Key = Cle;
            Logs = LesLogs;
        }

        public LogGroupe(IGrouping<string,Log> Groupe)
        {
            Key = Groupe.Key;
            Logs = Groupe.ToList();
        }
        public string Key { get; set; }

        public List<Log> Logs { get; set; }

        public int Occurence { get { return Logs.Count; } }

        public string Text { get { return string.Format("{0,-15}\t{1,7}\toccurence(s)", Key, Occurence); } }

        public override string ToString()
        {
            return Text;
        }
    }



Les évènement SelectionChanged des 2 listBox (lstModule et lstErreur) sont abonnés à cette méthode
        private void filtre_SelectedValueChanged(object sender, EventArgs e)
        {
            dgwLog.DataSource = null;

            //On récupère la listbox
            ListBox l = (sender as ListBox);
            if (l == null)//c'est pas une listbox => problème d'abonnement
                return;

            //on récupère la valeur sélectionnée
            LogGroupe filtre = l.SelectedItem as LogGroupe;
            if (filtre == null)
                return; // c'est pas un log ou il n'y a rien de sélectionné 

            if(filtre.Key == "Tous les enregistrements") //on affiche les logs concernés dans le datagridview
            {
                dgwLog.DataSource = filtre.Logs;
                return;
            }

            if(l == lstModule)
            {
                lstErreur.DataSource = null;

                //on va faire un groupeBy, à partir de la collection groupée par module, qui permet d'obtenir les valeurs de filtres par erreur et de connaitre le nombre d'occurences
                groupementErreur = filtre.Logs.GroupBy(g => g.Erreur).Select(g => new LogGroupe(g)).ToList();

                //On insère en début de liste la possibilité d'afficher toutes les occurences
                groupementErreur.Insert(0, new LogGroupe("Tous les enregistrements", filtre.Logs));

                lstErreur.DataSource = groupementErreur;

                return;
            }

            if(l == lstErreur)
            {
                //on affiche les log groupés par erreur dans le datagridview
                dgwLog.DataSource = filtre.Logs;
            }
        }



Là où tu charges le fichier (dans le load pour moi), tu mets ce code
        List<LogGroupe> groupementModule;
        List<LogGroupe> groupementErreur;
        private void Form1_Load(object sender, EventArgs e)
        {
            lstModule.DataSource = null;
            lstErreur.DataSource = null;
            ChargerFichier();

            //on va faire un groupeBy, qui permet d'obtenir les valeurs de filtres par module et de connaitre le nombre d'occurences
            groupementModule = lesLogs.GroupBy(l => l.Module).Select(g => new LogGroupe(g)).ToList();

            //On insère en début de liste la possibilité d'afficher toutes les occurences
            groupementModule.Insert(0, new LogGroupe("Tous les enregistrements", lesLogs));

            //On binde la liste de filtres
            lstModule.DataSource = groupementModule;
        }


Au premier chargement, tous les logs sont affichés, car par défaut c'est le premier filtre qui est sélectionné dans lstModule.


Si tu choisis un filtre, alors tous les enregistrements de ce filtre s'affichent, car cette fois c'est le premier filtre de lstErreur qui est sélectionné


Si tu choisi un filtre Erreur alors seulement les occurrences correspondantes s'affichent

0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
3 août 2020 à 09:11
Merci beaucoup c'est super intéressant et formateur pour moi, c'est exactement ce que je recherchais, je vois que tu as chargé plus de 300 000 lignes est ce qu'une pagination de 1000 lignes ou 500 par pages permettrais d'alléger encore l'affichage ?
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
3 août 2020 à 10:41
Peut-être mais il faut quand même charger tout le fichier (ou se limiter à 2M lignes comme on avait vu) car sinon tu auras les occurrences de filtres sur 1000 lignes.

C’est à toi de voir.

Avec 300k lignes une fois premier affichage fait c’est très rapide.
0
Merci beaucoup ça ma bien aidé, je vais maintenant m'amuser sur un autre projet ;)
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
10 août 2020 à 17:04
Si ça te convient, pense à marquer le sujet résolu
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
19 août 2020 à 15:05
Finalement j'ai remarqué un soucis, quand je relance une acquisition un de mes listbox saute et deviens vide ...
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
19 août 2020 à 18:15
Tu pourrais être plus précis?
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
20 août 2020 à 12:04
Je ne sais pas réellement expliquer mais je peux être amener à relancer un trie de log, une fois celui ci finis une de mes listbox deviens vide
premiere fois que je lance l'analyse

la seconde fois si c'est le même fichier
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
21 août 2020 à 21:32
Bonsoir

à ChargerFichier, remplace

        List<Log> lesLogs = new List<Log>();//liste de tous les logs

        private void ChargerFichier()
        {
            string[] lignes = File.ReadAllLines("LogisticCore300120.log");//chaaque ligne est chagée dans un emplacement de tableau


par
        List<Log> lesLogs;

        private void ChargerFichier()
        {
            lesLogs = new List<Log>();//remise à zéro de la liste
            string[] lignes = File.ReadAllLines("LogisticCore300120.log");//chaaque ligne est chagée dans un emplacement de tableau

0