Convertir fichier CSV

SPI_123 Messages postés 1 Date d'inscription jeudi 5 novembre 2015 Statut Membre Dernière intervention 5 novembre 2015 - 5 nov. 2015 à 19:00
SPI_ELEC Messages postés 11 Date d'inscription jeudi 5 novembre 2015 Statut Membre Dernière intervention 31 mars 2016 - 18 nov. 2015 à 14:33
Bonsoir,
En C#.Net, je souhaite convertir des fichiers .csv en un seul fichier Excel.
Dans un premier temps, je sélectionne mes fichiers .csv dans une ListBox, ensuite je souhaite faire une recherche par le nom de mes fichiers csv pour pouvoir sélectionner les bons fichiers et mettre les contenus dans la bonne colonne dans mon fichier excel. Idem pour les autres fichiers csv.
mes fichiers csv on tous un nom différent.
je ne sais pas comment m y prendre pour coder tout cela !!
Merci à tous pour votre aide.
Seb

8 réponses

Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
5 nov. 2015 à 19:29
Bonsoir, il n'y a qu'une colonne dans tes csv?

0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
5 nov. 2015 à 19:29
Quel est le lien entre le nom de fichier et le numéro ou nom de colonne
0
cs_louis14 Messages postés 793 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 10 février 2021 8
6 nov. 2015 à 08:33
Bonjour,
difficile à comprendre ce que tu veux faire :
- un fichier Excel ou un nouveau fichier csv
- y a-t-il un entête dans tes fichiers csv qui décrit tes variable,
- toutes les questions de Whismeril nécessitent une réponse

Bien écrire tout cela sur une page, permet de comprendre ce qu'il y a à faire.
Bonne réflexion
0
SPI_ELEC Messages postés 11 Date d'inscription jeudi 5 novembre 2015 Statut Membre Dernière intervention 31 mars 2016
6 nov. 2015 à 09:18
Bonjour à tous,
j ai plusieurs fichiers csv avec sur chaque fichier plusieurs colonnes, je veux récupérer un colonne différente sur chaque fichier csv et créer un fichier excel avec le regroupement des différentes colonnes de mes fichiers csv
j ai lister mes fichiers csv dans un listBox
mes fichiers csv ont tous un nom différents
l'entête de la colonne est contenu dans le nom du fichier csv, je pensais donc faire une recherche sur le nom du fichier pour ranger son contenu dans la bonne colonne mon fichier excel
Cordialement,
Sébastien
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
6 nov. 2015 à 14:16
Un exemple de nom de colonne Excel et de nom de fichier CEV stp.
D'autre part le nombre de colonne excel est fixe? Est ce toujours le même nom de colonne?
0
SPI_ELEC Messages postés 11 Date d'inscription jeudi 5 novembre 2015 Statut Membre Dernière intervention 31 mars 2016
6 nov. 2015 à 18:15
Bonsoir Whismeril,

Merci pour ton aide, le nombre de colonnes Excel est fixe et c'est toujours le même nom de colonnes (6) car 6 fichiers CSV à traiter

Fichier CSV :

10/26/15 12:21:17,0,1
10/26/15 12:21:20,0,1
10/26/15 12:35:44,0,1
10/26/15 12:35:48,0,1

Dans mon fichier Excel qui comporte un nombre fixe de colonnes je veux récupérer la colonne numéro 3 "0" et mettre le contenu dans la colonne correspondante à mon fichier Excel. Idem pour les 5 autres fichiers CSV qui rempliront des 5 autres colonnes de l Excel
la disposition des données dans les 6 CSV est toujours identiques.
les deux premières colonnes du fichier Excel sont remplies avec l heure et la date des fichiers CSV

Cordialement,

Sébastien
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
6 nov. 2015 à 18:34
Si dans 2 fichiers CSV, il y a la même heure, exactement, je suppose que dans l'excel les données seront sur la même ligne.
Mais si les horaires sont différents faut il que cela soit trié?

Tu n'as toujours pas expliqué le lien entre le nom des fichiers et le nom des colonnes
0
SPI_ELEC Messages postés 11 Date d'inscription jeudi 5 novembre 2015 Statut Membre Dernière intervention 31 mars 2016
7 nov. 2015 à 14:37
Bonjour,
le lien entre le nom des fichiers et le nom des colonnes:
dans le nom de mon fichier CSV il y a le nom de la colonne ou mettre les données dans une de mes colonnes dans mon fichier excel
Cordialement,
Sébastien
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
7 nov. 2015 à 15:03
Ça tu l'as déjà dit, si je redemande c'est que ça n'est pas suffisamment précis.

Dans fichieravecunnomcompletementnimportequoi.csv, il y a "a" mais si je cherche tous les fichiers avec "a" pour les mettre dans la colonne A ça va pas le faire.
0
SPI_ELEC Messages postés 11 Date d'inscription jeudi 5 novembre 2015 Statut Membre Dernière intervention 31 mars 2016
7 nov. 2015 à 17:14
Exemple de nom de mes fichiers csv :

Log_SOM.HMISCUXA5.APPLICATION.P29.PD1510260
Log_SOM.HMISCUXA5.APPLICATION.P29.TPDD1510260

sur le premier fichier, j aimerai récupérer les infos de la 3 eme colonne et les mettent dans la colonne "PD" de mon excel.
pour le deuxieme fichier csv, j aimerai recuperer les infos de le 3 eme colonne et les mettent dans la colonne "TPD" de mon excel
etc ......
en fait j aimerai identifier quel fichier est traité ( identification par son nom car le nom contient le nom de la cellule excel) mais je ne sais pas comment codé tout cela !
Merci pour ton aide Whismeril
Séb
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
7 nov. 2015 à 19:48
Ok dernière info, par rapport à l'heure, si dans deux fichiers les heures sont différentes, faut il trier?
0
SPI_ELEC Messages postés 11 Date d'inscription jeudi 5 novembre 2015 Statut Membre Dernière intervention 31 mars 2016
8 nov. 2015 à 09:41
Bonjour Whismeril,
non pas de tri
Cordialement,
Bon week end à toi
Sébastien
0

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

Posez votre question
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
8 nov. 2015 à 14:02
OK

on a à peu près tout.

En supposant que tu sois absolument certain que la combinaison de caractères correspondant à ton nom de colonne ne peut jamais apparaitre ailleurs dans un nom de fichier, on peut utiliser la méthode Contains.

//filename étant un string contenant le nom d'un fichier

if (filename.Contains("TPD"))
....


Cependant il faut tester indépendamment chaque fichier pour chaque nom de colonne, tu n'en as que 4, c'est gérable, mais si ça évolue, peut-être que cela deviendra plus compliqué.

Je te conseille donc d'utiliser une Regex, qui aura l'avantage de tester si un nom de fichier correspond à un modèle prévisible et d'en extraire le nom de colonne en même temps.
  • Hypothèse 1: tout ce qui est autour du nom de colonne est toujours pareil (peu probable, mais on commence simple)


La Regex devra trouver Debut de texte Log_SOM.HMISCUXA5.APPLICATION.P29.Nom de Fichier1510260.csvFin de texte

Attention je pars du principe que le nom de colonne n'est constitué que de lettres majuscules, et que dans le 2eme nom le DD est un faute de frappe.

            string filename = "Log_SOM.HMISCUXA5.APPLICATION.P29.TPD1510260.csv";
            if (Regex.IsMatch(filename, "^Log_SOM.HMISCUXA5.APPLICATION.P29.[A-Z]+1510260.csv$"))


On voit que le modèle est tout le texte, sauf le nom de colonne à l'emplacement duquel je cherche un caractère compris entre A et Z pouvant se répéter plusieurs fois.
  • Hypothèse 2: Avant le nom, il y a 4 blocs de caractères alphanumériques séparés par un point et après le nom, des chiffres.

            if (Regex.IsMatch(filename, @"^(\w+\.){4}[A-Z]+\d+\.csv$"))


Si le modèle est différent, je t'invite à te renseigner sur le web sur les Regex et leur application en C#, d'autre part il y a cette source, très utile pour les tester:
http://codes-sources.commentcamarche.net/source/41969-tester-et-compiler-de-regex-sauvegarde-gestion-des-regex-en-xml

Maintenant, avec cette même Regex, on va extraire le nom de la colonne, pour cela on va ajouter un groupe:

            Match m = Regex.Match(filename,@"^(\w+\.){4}(?<col>[A-Z]+)\d+\.csv$");

            string maCol;
            if (m.Success)
            {
                maCol = m.Groups["col"].Value;
            }



Maintenant il s'agit d'associer chaque fichier avec sa colonne, pour cela un dictionnaire est une bonne solution.

En effet, c'est une collection ou chaque item est constitué d'une clé et d'une valeur. Dans notre cas la clé sera le nom de col et la valeur le nom de fichier.

Pour retourner la collection des fichiers qui correspondent à notre modèle, on va se servir de la classe Directory et de sa méthode GetFiles:
            Directory.GetFiles(@"C:\Test", "*.*", SearchOption.AllDirectories);
cette instruction va retourner tous les chemins de fichiers de tous type contenu dans C:\Test et ses sous répertoires:
"C:\\Test\\Log_SOM.HMISCUXA5.APPLICATION.P29.TPD1510260.csv"
"C:\\Test\\Toto.docx"
"C:\\Test\\Un autre CSV.csv"
"C:\\Test\\Sous Dossier\\Log_SOM.HMISCUXA5.APPLICATION.P29.PD1510260.csv"


on peut restreindre aux csv:
            Directory.GetFiles(@"C:\Test", "*.csv", SearchOption.AllDirectories);



A partir de là, on peut faire une boucle sur files (foreach par exemple), tester notre regex, et si c'est bon alimenter notre dictionnaire.

On peut aussi faire une requête Linq.

            string[] files = Directory.GetFiles(@"C:\Test", "*.csv", SearchOption.AllDirectories);

            Regex maRegex = new Regex(@"^(\w+\.){4}(?<col>[A-Z]+)\d+\.csv$");
           
            Dictionary<string,string> monDico = (from f in files
                                                 let m = maRegex.Match(Path.GetFileName(f))
                                                 where m.Success
                                                 select new
                                                 {
                                                     Fichier = f,
                                                     Col = m.Groups["col"].Value
                                                 }
                                                 ).ToDictionary(i => i.Col, i => i.Fichier);


L'objet Path permet, ici, de ne prendre que le nom de fichier sur le chemin complet.
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
Modifié par Whismeril le 8/11/2015 à 15:15
Pour lire un fichier texte, on peut utiliser l'objet File.

La méthode ReadAllTexte retourne le contenu complet dans un string, il faut ensuite le découper en ligne et découper chaque ligne.

On peut gagner une étape avec ReadAllLines qui retourne un tableau avec chacune des lignes.

string[] lignes = File.ReadAllLines(monDico["TPD"]);


Pour découper un texte avec un ou des séparateur, on va utiliser la méthode split de l'objet string.

string[] valeurs = "10/26/15 12:21:17,0,1".Split(',');


dans valeur, il y aura
"10/26/15 12:21:17"
"0"
"1"


Pour ensuite correctement disposer les données dans le fichier excel, on va écrire une classe:

    public class DonneesSpiELec
    {
        public DateTime Datation { get; set; }

        public string ColTPD { get; set; }

        public string ColPD { get; set; }



Ensuite on compile tout ça dans une liste
           List<DonneesSpiELec> mesDonnees = new List<DonneesSpiELec>();

            foreach(string cle in monDico.Keys)
                foreach(string l in File.ReadAllLines(monDico[cle]))
                {
                    string[] valeurs = l.Split(',');
                    DateTime date = DateTime.ParseExact(valeurs[0], "MM/dd/yy HH:mm:ss" ,CultureInfo.InvariantCulture);//on extrait et converti la date

                    DonneesSpiELec donnee = mesDonnees.Find(x => x.Datation == date);//on cherche si une donnée a déjà été enregistrée pour cette datation
                    if (donnee == null)//la donnée n'existe pas encore
                    {
                        donnee = new DonneesSpiELec();
                        donnee.Datation = date;
                        mesDonnees.Add(donnee);
                    }

                    switch(cle)//on rempli le champ qui va bien
                    {
                        case "TPD":
                            donnee.ColTPD = valeurs[1];
                            break;

                        case "PD":
                            donnee.ColPD  = valeurs[1];
                            break;

                        default:
                            throw new Exception("Colonne non définie");
                    }

                    

                }


Modérer m'amène à intervenir dans de nombreux posts, mais les seuls langages que je connaisses sont le C# et un peu de VB. Pour vos codes pensez à la coloration.
Réponse trouvée ->Question Résolue
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
8 nov. 2015 à 14:54
Enfin pour excel,
j'ai fait une classe montrant un certains nombre de fonctionnalité en pilotage du logiciel
http://codes-sources.commentcamarche.net/source/50624-piloter-excel-via-microsoft-office-interop-excel

Sinon, on peut directement écrire en openxml, mais ça je n'ai pas fait.
0
SPI_ELEC Messages postés 11 Date d'inscription jeudi 5 novembre 2015 Statut Membre Dernière intervention 31 mars 2016
18 nov. 2015 à 14:33
Bonjour,
Merci pour toutes ces infos,
je vais mettre en oeuvre tout cela
Cordialement,
Sébastien
0
Rejoignez-nous