Convertir fichier CSV

SPI_123 1 Messages postés jeudi 5 novembre 2015Date d'inscription 5 novembre 2015 Dernière intervention - 5 nov. 2015 à 19:00 - Dernière réponse : SPI_ELEC 11 Messages postés jeudi 5 novembre 2015Date d'inscription 31 mars 2016 Dernière intervention
- 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
Afficher la suite 

Votre réponse

16 réponses

Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - 5 nov. 2015 à 19:29
0
Merci
Bonsoir, il n'y a qu'une colonne dans tes csv?

Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - 5 nov. 2015 à 19:29
Quel est le lien entre le nom de fichier et le numéro ou nom de colonne
Commenter la réponse de Whismeril
cs_louis14 788 Messages postés mardi 8 juillet 2003Date d'inscription 8 mars 2017 Dernière intervention - 6 nov. 2015 à 08:33
0
Merci
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
Commenter la réponse de cs_louis14
SPI_ELEC 11 Messages postés jeudi 5 novembre 2015Date d'inscription 31 mars 2016 Dernière intervention - 6 nov. 2015 à 09:18
0
Merci
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
Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - 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?
SPI_ELEC 11 Messages postés jeudi 5 novembre 2015Date d'inscription 31 mars 2016 Dernière intervention - 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
Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - 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
Commenter la réponse de SPI_ELEC
SPI_ELEC 11 Messages postés jeudi 5 novembre 2015Date d'inscription 31 mars 2016 Dernière intervention - 7 nov. 2015 à 14:37
0
Merci
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
Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - 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.
SPI_ELEC 11 Messages postés jeudi 5 novembre 2015Date d'inscription 31 mars 2016 Dernière intervention - 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
Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - 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?
SPI_ELEC 11 Messages postés jeudi 5 novembre 2015Date d'inscription 31 mars 2016 Dernière intervention - 8 nov. 2015 à 09:41
Bonjour Whismeril,
non pas de tri
Cordialement,
Bon week end à toi
Sébastien
Commenter la réponse de SPI_ELEC
Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - 8 nov. 2015 à 14:02
0
Merci
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.
Commenter la réponse de Whismeril
Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - Modifié par Whismeril le 8/11/2015 à 15:15
0
Merci
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
Commenter la réponse de Whismeril
Whismeril 12023 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 18 septembre 2018 Dernière intervention - 8 nov. 2015 à 14:54
0
Merci
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.
Commenter la réponse de Whismeril
SPI_ELEC 11 Messages postés jeudi 5 novembre 2015Date d'inscription 31 mars 2016 Dernière intervention - 18 nov. 2015 à 14:33
0
Merci
Bonjour,
Merci pour toutes ces infos,
je vais mettre en oeuvre tout cela
Cordialement,
Sébastien
Commenter la réponse de SPI_ELEC

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.