Affichage .csv sur applicatif c#

Résolu
rachidsysteme67 - 7 mars 2013 à 15:22
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 - 18 mars 2013 à 12:00
Bonjour, je suis débutant en programmation, et je galère.

Je dois afficher un fichier .csv (9 colonnes de types différents composées de plusieurs lignes) sur un Datagridview avec visual studio 2005 et Framework 2.0

Comment puis-je faire pour afficher ces données sur mon DGV avant de sélectionner les colonnes ou éléments à récuperer sur mes différentes tables de ma base sqlserver ?

J'avais tenter le coup avec un BULK INSERT directement sur ma table mais sqlserver 2005 express m'indique une multitude d'erreurs, d'où mon changement de stratégie avec l'appli c# ...

PS : les colonnes du csv sont des ";"

Merci d'avance

17 réponses

rachidsysteme67
7 mars 2013 à 16:20
J'aurai peut être du choisir le forum c#? si c'est le cas merci à code sources de le déplacer !
1
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
11 mars 2013 à 15:50
Bonjour,

le plus simple (enfin pour moi...)

Admettons que tu aies 3 colonnes (pour l'exemple)

tu écris une classe de ce style

       class MaClasse
    {
        public MaClasse(string ligne)
        {
            ImportUneLigne(ligne);
        }

        public string Prenom { get; set; }

        public int Taille { get; set; }

        public DateTime DateNaissance { get; set; }

        private void ImportUneLigne(string ligne)
        {
            string[] val = ligne.Split(";");
            this.Prenom = val[0];
            this.Taille = Convert.ToInt32(val[1]);//tu peux aussi utiliser int.TryParse() si tu n'es pas sur que tous les eregistrements soient des int
            this.DateNaissance = Convert.ToDateTime(val[2]);// idem avec DateTime.TryParse()
        }
    }

C'est elle qui fait le boulot de split et de convertion de type.

Ta première boucle devient inutille, dans la deuxième tu crées une instance de MaClasse que tu stockes dans une List<MaClasse>
            List<MaClasse> maListe = new List<MaClasse>();
            while (reader.Peek() != -1)
            {
                maListe.Add( new MaClasse( reader.ReadLine()));
            } 


A la fin de cette boucle tu "bindes" la liste sur le datagridview, soit comme je te l'ai écrit plus haut en affectant la liste à la propriété DataSource, soit si tu veux personnaliser les noms de colonnes ou si tu veux aussi lier d'autres controles en utilisant cette méthode
Whismeril
1
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
17 mars 2013 à 21:34
dans l'absolue il faudrait tester si ta ligne est "importable", mais si tu es sur de l'intégrité du fichier et qu'il n'y a qu'une ligne d'entete le plus simple est de la sauter avant le boucle

reader.ReadLine();//je lis la première ligne

while (reader.Peek()!= -1) 
{ 
   rowValue = reader.ReadLine (); 
   CellValue = rowValue.Split (';'); 
   dataGridView1.Rows.Add (CellValue); 
}


Pense à utiliser les balises de code.
Whismeril
1
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
17 mars 2013 à 22:26
J'ai regardé vite fait le bout de fichier que tu m'as envoyé.

Comme je te l'ai dit plus haut je suis partisant d'écrire une classe qui correspond à la sortie que tu veux (je n'ai pas fait toutes les colonnes)
    public class CsvRachidSystem
    {
        public bool Import(string ligne)
        {
            string[] tableau = ligne.Split(';');

            //je teste si la première colonne peut être convertie en long, c'est un test possible pour écarter les lignes d'entetes
            long valeur;
            if (long.TryParse(tableau[0], out valeur))
            {
                //si oui on importe
                TimeMs = valeur;
                Init(tableau);
                return true;//et je valide
            }
            else return false;// invalide
        }


        /// <summary>
        /// importe et converti les données
        /// </summary>
        /// 


        private void Init(string[] tableau)
        {
            MsgNumber = Convert.ToInt32(tableau[4]);
            TimeString = Convert.ToDateTime(tableau[13]);
            MsgText = tableau[14];
            PLC = tableau[15];

            Date2 = TimeString.AddMilliseconds(TimeMs);//si j'ai bien compris c'est des millisecondes à ajouter?

        }

        public int MsgNumber { get; set; }

        public string MsgText { get; set; }

        public DateTime TimeString { get; set; }

        public DateTime Date2 { get; set; }

        public string PLC { get; set; }

        public long TimeMs { get; set; }
    }



et le code qui permet de lire et d'afficher le fichier (pour l'exemple il est dans un bouton)

        private void button4_Click(object sender, EventArgs e)
        {
            List<CsvRachidSystem> maListe = new List<CsvRachidSystem>();

            FileStream fs = new FileStream(@"E:\Archive_alarmes0.csv", FileMode.Open);
            StreamReader sr = new StreamReader(fs);

            while (sr.Peek() != -1)
            {
                CsvRachidSystem item = new CsvRachidSystem();

                if (item.Import(sr.ReadLine())) maListe.Add(item);
            }

            dataGridView1.DataSource = maListe;
            
        }


Pour ton histoire de long, vu que la colonne s'appelle TimeMs, j'ai supposé qu'il s'agit de millisecondes à ajouter à l'autre date.

Whismeril
1

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

Posez votre question
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
18 mars 2013 à 12:00
De rien, dans mon exemple c'est directement la List<T> que tu pourras exporter vers sql.

Si la solution te convient, clique sur "réponse acceptée", le sujet apparaitra résolu


Whismeril
1
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
7 mars 2013 à 16:24
Au final ta question c'est l'import du csv vers la datagridview ou l'export vers sql server?

Pour l'importn cherche sur le site les codes pour lire du fichiers texte.
Tu importes ligne par ligne, tu parses dans une classe que tu as prélablement préparée (par string.split() ou une regex) et tu mets chaque enregistrement dans une list<T>.

A la fin tu affectes cette liste au datasource de ta grille.

Pour sqlserver, connais pas.


Whismeril
0
rachidsysteme67
8 mars 2013 à 08:37
Merci @Whismeril
L'import d'un csv dans un dgv. Ton explication parait simple comme ça, je n'arrive pas à la mettre en pratique là ...
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
8 mars 2013 à 16:23
regarde cette source, je ne l'ai pas essayée mais c'est un début.



Whismeril
0
rachidsysteme67
11 mars 2013 à 15:08
Cool, j'ai pu afficher mon fichier sur un dgv .

Une premier boucle pour les titres de colonnes ";"

for (int i = 0; i <= CellValue.Length-1; i ++)
{
DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
column.Name = CellValue [i];
column.HeaderText = CellValue [i];
dataGridView1.Columns.Add (column);
}

Et une seconde pour la séparation des lignes"\n"

while (reader.Peek()!= -1)
{
rowValue = reader.ReadLine ();
CellValue = rowValue.Split (';');
dataGridView1.Rows.Add (CellValue);
}

Mais je fais comment pour parser chaque colonne en un type spécifique?

Merci ...
0
rachidsysteme67
11 mars 2013 à 16:12
Ok j'vais essayer merci pour tout, tu m'es d'une aide précieuse vraiment
je te dirai, ou j'en suis en testant !
0
rachidsysteme67
12 mars 2013 à 12:48
j'ai tenté le coup mais problème de conversion sur chacune des colonnes a typé

Ma ligne "sting" est constituée d'éléments typés suivants
-long(qui en fait est un Timestamp)
-byte
-int
-int
-int
-int
-int
-int
-int
-int
-Date Time ( qui est iindiqué en string =)"7. 2. 2013 7:04:30")
-string
-string

Le Date time, est un début, additionné au timestamp doit me donner une date de fin
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
12 mars 2013 à 14:42
Pour les long, int et byte avec ConvertTo, ou tryparse comme je te l'ai écrit plus haut.

Pour le DateTime utilise la méthode Replace() pour changer les espaces et les . en slash.

Pour le timeSpan, il y a une méthode static TimeSpam.FromLong ou un truc comme ça.


Whismeril
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
12 mars 2013 à 16:27
Pour tes histoires de dates ceci fontcionne:

            DateTime date1;
            DateTime date2;
            TimeSpan duree = TimeSpan.FromTicks(1234567890);

            if (DateTime.TryParse("7. 2. 2013 7:04:30", out date1))//teste si le string est convertible en DateTime
                date2 = date1 + duree;// Si oui cacule la deuxième date



Whismeril
0
rachidsysteme67
14 mars 2013 à 11:21
laisse tomber aucune conversion ne se fait sans doute à cause de la 1ere ligne qui est le titre des colonnes, vu que j'ai opté pour le bind, mais là franchement je suis à bout, et ce n'est que les prémices de mon appli.
0
Whismeril Messages postés 19026 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 20 avril 2024 656
14 mars 2013 à 16:05
Ha oui il faut que tu sautes la ligne d'entete

Whismeril
0
rachidsysteme67
17 mars 2013 à 19:48
peux tu me dire comment faire avec cette boucle pour ne pas prendre en considération ma 1ere ligne :

while (reader.Peek()!= -1)
{
rowValue = reader.ReadLine ();
CellValue = rowValue.Split (';');
dataGridView1.Rows.Add (CellValue);
}
0
rachidsysteme67
18 mars 2013 à 08:38
Merci pour tout
0
Rejoignez-nous