Afficher dans un DataGridView à partir d'une classe

Fermé
Melman - 27 mars 2020 à 10:15
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 - 17 avril 2020 à 13:06
Bonjour, je me permet de poser ma question car j'ai une classe qui me permet de récupérer des valeurs à partir d'un fichier texte, j'aimerai pouvoir les renvoyer sur ma form d'origine qui elle contient mon DataGrid et pouvoir justement les afficher dans le DataGrid, j'aimerais aussi savoir si le DataGrid me permettais d'afficher une grande quantité de valeurs.
Merci à vous ^^



Configuration: Windows / Chrome 80.0.3987.149

38 réponses

Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
9 avril 2020 à 09:54
Pour le null, la méthode Parse peut retourner un Log null si le format de la date n'est pas reconnu, ou si le nom de fichier ne commence par par Logis

Option 1, tu ignores ce log
        public void ChargerFichier(int i, List<string> cheminFichierOk)
        {
            for (int j = 0; j < cheminFichierOk.Count - i; j++)
            {
                IEnumerable<string> lines = File.ReadLines(cheminFichierOk[j]);
                foreach (var item in lines)
                {
                    LogParse leLog = LogParse.Parse(item, Path.GetFileName(cheminFichierOk[j]));
                    if(leLog != null)//ici
                        lesLogs.Add(leLog);
                }
            }
            lesLogs = lesLogs.OrderBy(x => x.Datation).ToList();
        }


option 2, il faut modifier Parse pour retourner un log par défaut et / ou partiellement remplir

par exemple
        public static LogParse Parse(string lignes, string nomFichier)
        {
            if (nomFichier.StartsWith("Logis"))
            {
                string[] ligneArray = lignes.Split('\t'); //sépare les chaînes à partir
                Match m = Regex.Match(lignes, @"(?<mois>\d\d?)?/(?<jour>\d\d?)?/(?<annee>\d{4})?\s+(?<heure>\d\d?)?:(?<minute>\d\d?)?:(?<seconde>\d\d?)?\s+(?<ampm>[AP]M)?:(?<ms>\d{1,3})?");
                if (m.Success)
                {
                    int jour = int.Parse(m.Groups["jour"].Value);
                    int mois = int.Parse(m.Groups["mois"].Value);
                    int annee = int.Parse(m.Groups["annee"].Value);
                    int heure = int.Parse(m.Groups["heure"].Value);
                    int minute = int.Parse(m.Groups["minute"].Value);
                    int secondes = int.Parse(m.Groups["seconde"].Value);

                    string MS = m.Groups["ms"].Value;
                    int ms = 0;
                    if (!string.IsNullOrWhiteSpace(MS))
                    {
                        ms = int.Parse(MS);
                        if (MS.Length == 1)
                            ms *= 100;
                        else if (MS.Length == 2)
                            ms *= 10;
                    }
                    DateTime date = new DateTime(annee, mois, jour, heure, minute, secondes, ms);
                    if (m.Groups["ampm"].Value == "PM")
                        date = date.AddHours(12);
                    return new LogParse
                    {
                        Datation = date,
                        Identificateur = "Nom",
                        Module = ligneArray[1],
                        Type = ligneArray[2],
                        Info = ligneArray[3],
                        Details = ligneArray[4],
                    };
                }
                return new LogParse
                    {
                        Identificateur = "Date Invalide",
                        Module = ligneArray[1],
                        Type = ligneArray[2],
                        Info = ligneArray[3],
                        Details = ligneArray[4],
                    };
            }
          return new LogParse
                    {
                        Identificateur = "Fichier Invalide"
                    };
                }

0
Finalement j'ai réussi à trouver le problème "1/30/2020 4:01:27 PM:359" ici je prenais en compte qu'il y avais obligatoirement AM ou PM, "11/02/2020 08:20:11:974" et ici pas de AM ou PM, du coup j'ai modifié mon regex :
(?<mois>\d\d?)?/(?<jour>\d\d?)?/(?<annee>\d{4})?\s+(?<heure>\d\d?)?:(?<minute>\d\d?)?:(?<seconde>\d\d?)?(?<ampm>\s[AP]M)?:(?<ms>\d{1,3})?
0
Petit soucis, quand je veux analyser mon fichier plus volumineux il me remet l'erreur de la date nul mais quand un fichier qui fonctionne a été analyser avant on arrive sur l'erreur OutOfMemory
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
9 avril 2020 à 11:40
Une chose à la fois.
Pour la date null, as tu juste modifié la regex ou aussi appliqué l'une ou l'autre des mes options.
Si tu as appliqué l'une ou l'autre de mes options alors, peut-être faut il mettre une date par défaut dans les 2 return partiels

Si après avoir testé ça plantevencore, peux tu poster une impression d'écran du moment où ça plante, avec si possible des espions des variables utiles.
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
Modifié le 9 avril 2020 à 12:17
Quand je laisse le deuxième return new LogParse il m'affiche une erreur "IndexOutOfRangeException" quand je l'enlève plus d'erreur à ce passage ni de x nu
ll met un OutOfMemory
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
9 avril 2020 à 12:59
Le out of memory, c'est que ton fichier est trop gros.
On verra plus tard.

Le IndexOutOfRangeException, c'est parce que le tableau ligneArray à moins de 5 items.
Pour savoir pourquoi, il faut regarder le contenu de la ligne au complet.
Et ensuite modifier le code en conséquence.
Si tu ne sais pas modifier, poste le contenu de la ligne.
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
9 avril 2020 à 14:29
je vois pas du tout je suis perdu la...

Mes lignes ressemble à ça : 11/02/2020 08:28:13:88 Traffic Control C_BEGIN InterfacePilotageLogique::initInterface [L:87]
11/02/2020 08:28:13:88 Traffic Control C_INIT InterfacePilotageLogique::initInterface [L:88] InterfacePilotageLogique n°8
11/02/2020 08:28:13:88 Traffic Control C_END InterfacePilotageLogique::initInterface [L:90] CodeResult = CODE_OK
11/02/2020 08:28:13:88 Traffic Control C_CREATE InterfacePhysiquePilotageAMQP::InterfacePhysiquePilotageAMQP [L:54] InterfacePhysiquePilotageAMQP created
11/02/2020 08:28:13:88 Traffic Control C_BEGIN InterfaceLogique::setIntfPhysique [L:37]
11/02/2020 08:28:13:88 Traffic Control C_UPDATE InterfaceLogique::setIntfPhysique [L:46] Association avec interface physique n°1 de type 100
11/02/2020 08:28:13:88 Traffic Control C_END InterfaceLogique::setIntfPhysique [L:51] CodeResult = CODE_OK
11/02/2020 08:28:13:88 Traffic Control C_BEGIN InterfacePhysiquePilotageAMQP::initInterface [L:85] initInterface
11/02/2020 08:28:13:88 Traffic Control N_DEBUG InterfacePhysiquePilotageAMQP::initAMQPclient [L:397] Start Initializing AMQP...
11/02/2020 08:28:13:104 Traffic Control N_DEBUG InterfacePhysiquePilotageAMQP::initAMQPclient [L:436] AMQP Initialization status: 0
11/02/2020 08:28:13:104 Traffic Control C_BEGIN InterfacePhysiquePilotageAMQP::initMsgReceive [L:1443] initMsgReceive
11/02/2020 08:28:13:104 Traffic Control C_CREATE AMQPReceiverThread::AMQPReceiverThread [L:37] AMQPReceiverThread
0

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

Posez votre question
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
9 avril 2020 à 14:52
Je te demande la ligne qui est lue au moment où ça plante.
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
Modifié le 9 avril 2020 à 15:09
j'ai trouver j'ai une ligne vide qui me fait planter à ce moment la !
11/02/2020 08:28:13:885 Traffic Control N_DEBUG InterfacePhysiquePilotageAMQP::sendMessage [L:268] Message contents = {"slowMotions":[{"agvId":1,"on":false,"pattern":0,"speed":0},{"agvId":15,"on":false,"pattern":0,"speed":0}]}

11/02/2020 08:28:13:885 Traffic Control C_END InterfacePhysiquePilotageAMQP::sendMessage [L:293] sendMessage

j'ai un saut de ligne et la ça veut pas, donc faut que je gère ce genre de ligne
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
9 avril 2020 à 21:25
Tu peux essayer, quand le split ne retourne pas assez d’items, de concaténer avec la ligne suivante
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
10 avril 2020 à 11:19
Le soucis c'est que je n'aurais toujours pas la date de mon fichier... Mais je suis en train de tester l'option de concaténation
0
MelmanM Messages postés 20 Date d'inscription jeudi 9 avril 2020 Statut Membre Dernière intervention 20 août 2020
Modifié le 10 avril 2020 à 12:11
Je retombe toujours sur la même erreur mes tests ne sont pas concluant ^^'
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
10 avril 2020 à 18:23
Je tache d'y regarder demain
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
11 avril 2020 à 10:24
Ha pardon, j'avais mal lu/compris ton message.
J'ai cru que tu avais un log écrit sur 2 lignes.
Mais en fait, tu as une ligne vide.

Je te propose donc 2 choses:
  • ignorer les lignes vides.
  • ignorer les lignes qu'on ne sait pas lire (sans planter) et les logguer dans un fichier.


A la fin, signaler s'il y a eu des erreurs de lecture, afin d'analyser les lignes et adapter le code si besoin

La méthode LogParse.Parse
        public static LogParse Parse(string lignes, string nomFichier)
        {
            if (nomFichier.StartsWith("Logis"))
            {
                string[] ligneArray = lignes.Split('\t'); //sépare les chaînes à partir
                if (ligneArray.Length != 5)
                    return null;

                Match m = Regex.Match(lignes, @"(?<mois>\d\d?)?/(?<jour>\d\d?)?/(?<annee>\d{4})?\s+(?<heure>\d\d?)?:(?<minute>\d\d?)?:(?<seconde>\d\d?)?\s+(?<ampm>[AP]M)?:(?<ms>\d{1,3})?");
                if (m.Success)
                {
                    int jour = int.Parse(m.Groups["jour"].Value);
                    int mois = int.Parse(m.Groups["mois"].Value);
                    int annee = int.Parse(m.Groups["annee"].Value);
                    int heure = int.Parse(m.Groups["heure"].Value);
                    int minute = int.Parse(m.Groups["minute"].Value);
                    int secondes = int.Parse(m.Groups["seconde"].Value);

                    string MS = m.Groups["ms"].Value;
                    int ms = 0;
                    if (!string.IsNullOrWhiteSpace(MS))
                    {
                        ms = int.Parse(MS);
                        if (MS.Length == 1)
                            ms *= 100;
                        else if (MS.Length == 2)
                            ms *= 10;
                    }
                    DateTime date = new DateTime(annee, mois, jour, heure, minute, secondes, ms);
                    if (m.Groups["ampm"].Value == "PM")
                        date = date.AddHours(12);
                    return new LogParse
                    {
                        Datation = date,
                        Identificateur = "Nom",
                        Module = ligneArray[1],
                        Type = ligneArray[2],
                        Info = ligneArray[3],
                        Details = ligneArray[4],
                    };
                }
            }
            return null;
        }


La méthode ChargeFichier
        public void ChargerFichier(int i, List<string> cheminFichierOk, out bool Erreur, string FichierErreur)
        {
            Erreur = false;
            for (int j = 0; j < cheminFichierOk.Count - i; j++)
            {
                string[] lines = File.ReadAllLines(cheminFichierOk[j]);
                for (int k = 0; k < lines.Length; k++)
                {
                    string item = lines[k];
                    if (string.IsNullOrWhiteSpace(item))
                        continue;//on ignore les lignes vides

                    LogParse leLog = LogParse.Parse(item, Path.GetFileName(cheminFichierOk[j]));
                    if (leLog != null)
                        lesLogs.Add(leLog);
                    else
                    {
                        Erreur = true;
                        if (!File.Exists(FichierErreur))
                            File.AppendAllText(FichierErreur, "Fichier;Ligne;Texte\r\n");//création du fichier avec la ligne d'entête

                            File.AppendAllText(
                            FichierErreur, 
                            string.Format("{0};{1};{2}\r\n", cheminFichierOk[j],k,item)
                            );
                    }
                }
            }
            lesLogs = lesLogs.OrderBy(x => x.Datation).ToList();
        }


Et la méthode du backgroundworker
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            DateTime dateDebut = this.dtpDebut.Value, dateFin = this.dtpFin.Value;
            int i = 0;
            //List<string> cheminFichier = new List<string> { "LogisticCore300120.log" };//ça c'est pour que ça marche chez moi
            bool Erreur = false;
            string erreurLog = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Erreurs.csv");

            cheminFichier = IntervaleFichierGlobal(lcPath, dateDebut, dateFin);
            ChargerFichier(i, cheminFichier, out Erreur, erreurLog);
            cheminFichier = IntervaleFichierGlobal(TraficPath, dateDebut, dateFin);
            ChargerFichier(i, cheminFichier, out Erreur, erreurLog);

            if (Erreur)
            {
                Process.Start(erreurLog);//on affiche le fichier
            }
        }


J'ai sauté une ligne dans le fichier, (ça s'est pas loggué, mais on pourrait si tu veux), modifié une date et supprimé une info dans une autre ligne.
Le fichier erreurs.csv est
Fichier;Ligne;Texte
LogisticCore300120.log;6;1/30/2020 4:01:27 	LOGMON	N_DEBUG	commandLine [L:55]  	CommandLine ok
LogisticCore300120.log;12;1/30/2020 4:01:27 PM:581	LOGMON	N_DEBUG	startWebServer [L:264]

0
Merci encore pour tes réponses ! J'ai testé les petites modifs et le texte retourner est ] (pour mon fichier volumineux) sinon mon fichier qui fonctionne me retourne bien les lignes que je met en erreur volontairement.
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
14 avril 2020 à 11:58
Bon

alors pour le fichier volumineux, il n'y a pas le choix, il faut le lire en plusieurs fois.
Peux tu mettre un point d'arrêt après
string[] lines = File.ReadAllLines(cheminFichierOk[j]);
pour voir si cette étape passe.
Si oui c'est "facile" il suffit de dire je traite d'abord X milliers de lignes, puis dans un second temps X milliers de nouvelles lignes etc...
Si non, il faudra lire le fichier en mode séquentiel.
0
Et le datagridview ne risque pas de poser problème en terme d'affichage ?
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
14 avril 2020 à 13:42
si on commençait par le début tu veux bien.
0
On rentre bien dans la boucle, l'exception apparait ici
 string[] ligneArray = lignes.Split('\t');
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
14 avril 2020 à 16:33
Il faut que tu comprennes qu'avec un fichier trop volumineux ça peut tomber n'importe ou dans le code.
Dés que tu atteints la quantité de mémoire disponible pour ton logiciel ça plante.
Donc ça n'est pas une ligne spécifique qui génère un OutOfMemory, c'est l'accumulation.

Ma question était est ce que ça va dépasse cette étape là:
string[] lines = File.ReadAllLines(cheminFichierOk[j]);


De ta réponse, je comprends que oui.
Maintenant, je voudrais savoir le nombre d'items dans string[] lines, tu devrais pouvoir le voir avec les outils de débugage, ou en tapant lines.Lenght dans la fenêtre d'exécution.
0
Dans mon string j'ai 10,464,487 item pour un fichier ^^'
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
14 avril 2020 à 16:41
OK même opération avec ton fichier qui fonctionne
0
312 053 lignes pour celui-ci
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
14 avril 2020 à 16:52
Ha oui y'a un rapport 33...

Bon, reprends le fichier trop gros.

Modifie le code ainsi
                string[] lines = File.ReadAllLines(cheminFichierOk[j]);
                for (int k = 0; k < lines.Length; k++)
                {
                    if(k > 313000 && k % 1000 == 0)
                          Console.WriteLine(k);

                    string item = lines[k];
                    if (string.IsNullOrWhiteSpace(item))
                        continue;//on ignore les lignes vides



Laisse aller jusqu'à planter, et à ce moment là regarde la dernière valeur de k et dit la moi.

0
Je suis à 2514000
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
14 avril 2020 à 17:44
Ok donc pour ce fichier, au bout d'un peu plus de 2,5 millions de lignes ton logiciel n'arrive plus à instancier des LogParse.
Alors je ne te parle même pas de les afficher.
En plus une instance de LogParse n'a pas une taille fixe, car elle est composée de strings dont la taille dépend du nombre de caractères.
On va faire un test avec les 2 premières millions de lignes.

Modifie ceci
for (int k = 0; k < 2000000; k++)

Si ça passe à mon avis on n'est pas loin du clash, si ça ne passe pas, essaye 1 500 000 puis 1 000 000, 500 000 jusqu'à ce que ça passe et ré-augmente petit à petit.
0
Bon un peut de bonne news, je me suis rendu compte que j'avais une erreur dans le nombre de fichier trouver et le nombre de fichier lu que j'ai régler du coup avec 2M de lignes cela fonctionne 2M1 aussi, arriver à 2M2
            lesLogs = lesLogs.OrderBy(x => x.Datation).ToList();
cette ligne me renvoie la jolie Erreur "OutOfMemory", par contre quand je n'obtient pas cette Erreur mon DataGridView affiche tout très facilement
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
15 avril 2020 à 17:40
OK, alors on va considerer qu'environ 2M de lignes c'est déjà bien.

Après
  string[] lines = File.ReadAllLines(cheminFichierOk[j]);


tu vas ajouter
File.WriteAllLines("test2M.log", File.ReadAllLines(cheminFichierOk[j].Take(2000000));
return;

tu exécutes une fois.
Tu vas vérifier dans le dossier de ton exe si le fichier test2M.log et bien créé.
SI oui, tu regardes sa taille (en octet, se sera plus simple pour la suite) et tu peux supprimer les 2 lignes ajoutée.

L'idée c'est de trouver la taille à partir de laquelle, il faudra faire un traitement "par morceau".
0
Cette ligne me renvoie l'erreur "ArgumentException" j'ai voulu mettre un chemin d'accès correct mais rien y fait
 string chemin = "test2M.log";
                File.WriteAllLines(chemin, File.ReadAllLines(cheminFichierOk[j].Take(2000000).ToString()));
0
Je l'ai donc fait à la main et j'ai obtenu (247 702 743 octets)
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
16 avril 2020 à 17:40
Je l'ai tapé de tête , j'ai p'tet écris une boulette.
Bon maintenant, il faut faire un choix.


Option 1
avant de lire le fichier, on regarde sa taille, et si elle dépasse disons 240 000 000 d'octets, on signale à l'opérateur que seules les 2M de premières lignes (environs) vont être afficher.
Il faudra alors une action de sa part pour afficher les 2M suivantes.

Option 2
on lit systématiquement par parquet, plus petits 2M de ligne c'est déjà énorme.

Option 3
Considérant que l'opérateur ne peut pas faire grand chose de 2M de lignes, je suppose qu'ensuite tu effectues des filtres. Je te propose de voir les choses dans l'autre sens, l'opérateur fait ses filtres et on ne va lire dans le fichier que les lignes concernées.

Option 4
je sais pas mais y'a certainement encore pleins de façon de voir les choses.
0
Je pencherai plus pour l'option 3, j'y avais déjà pensé avec un formulaire ou je peux sélectionner les logs que je veux afficher, je voulais que cela ce fasse après l'analyse au cas ou l'utilisateur était indécis mais si je comprends bien on fait le choix des logs à garder et si la ligne contient le dit log on la conserve et le reste ne sera pas conserver et donc à afficher ?
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 929
17 avril 2020 à 13:06
oui ça peut être ça
0