IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

[Interop.Excel]Forcer un type de données


Sujet :

C#

  1. #1
    En attente de confirmation mail
    Inscrit en
    Août 2007
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 174
    Points : 133
    Points
    133
    Par défaut [Interop.Excel]Forcer un type de données


    J'utilises sur mon projet le COM Excel 12.0 pour lire des excels (logique...)

    Mais dans une colonne, j'ai des numéros de série à 17 chiffres et get_Range.Value2 s'obstine à me renvoyer un type double (ex : 6,20064E+17)

    Coment faire pour récupérer la valeur en type long, car la cellule contient bien le numéro de série ?

    Merci pour votre aide

  2. #2
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Quel est le format de la cellule sous Excel ?
    Quel est le nombre dans la cellule (long ?) et quel est le nombre que tu obtiens (double ?) ?

  3. #3
    En attente de confirmation mail
    Inscrit en
    Août 2007
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 174
    Points : 133
    Points
    133
    Par défaut
    Le fichier lu est au format .csv donc la cellule est de type standard.

    Si j'ouvres le fichier avec Excel, il m'indique "2,00064E+17"
    Si je passes la cellule en format Personnalisée '0', j'obtiens '200064185399999000'

    Dans le code, je récupères ma cellule[1,2] = 2,00064E+17 de type double.
    Si je converti en entier, j'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Convert.ToUInt64(cells[1, 2])	
    200064000000000000	
    ulong
    Bref j'ai une perte de précision, donc comment je peux récupérer directement la vrai valeur (sous forme entier ou string, mais pas arrondi en double).

  4. #4
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Es-tu obligé d'utiliser Interop pour lire un fichier csv ? Il me semblerait beaucoup plus simple de lire le fichier au format texte.

    Ceci dit, j'ai fait un test de mon côté et je n'ai pas de perte de précision :
    - Je mets la valeur 200064185399999000 dans la cellule A1 (format Standard).
    - J'ai 2.00064E+17 qui s'affiche.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Range myRg = excelWks.get_Range("A1", "A1");
    Console.WriteLine(myRg.Value2);
    Console.WriteLine(myRg.Text);
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    2.00064185399999E+17
    2.00064E+17
    Comment fais-tu pour intégrer le fichier csv par Interop ?

  5. #5
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Décembre 2008
    Messages : 256
    Points : 311
    Points
    311
    Par défaut
    Citation Envoyé par User.Anonymous Voir le message

    J'utilises sur mon projet le COM Excel 12.0 pour lire des excels (logique...)
    A part que là que tu ne traites pas des fichiers Excel mais des fichiers texte (csv = fichier texte).
    Du coup, faire de l'interop pour lire des fichiers texte, c'est un peu comme utiliser un marteau-pilon pour casser une noisette.

  6. #6
    En attente de confirmation mail
    Inscrit en
    Août 2007
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 174
    Points : 133
    Points
    133
    Par défaut
    Alors petite précision, les fournisseurs envoient pour la plupart des fichiers sous format .xls dont celui ci mais pour une raison que j'ignore, il envoie dorénavant ce fichier en .csv en gardant la même structure.

    J'ai adapté le OpenFile afin de le lire sans refaire tous le code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    		public void OpenFile(string Delimiter)
    		{
    			if(oExcelApp != null)
    				CloseFile();
     
    			//SLB - 13/11/07
    			int del;
    			switch (Delimiter)
    			{
    				case "," :
    					del = 2;
    				break;
    				case ";" :
    					del = 4;
    				break;
    				case "TAB" :
    					del = 1;
    				break;
    				default :
    					del = 5; //Nothing
    				break;
    			}
    			//Ouvre le template
    			oExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
    			oExcelApp.Visible = false;
    			oExcelApp.AskToUpdateLinks = false;
    			oExcelApp.DisplayAlerts = false;
    			oBooks = oExcelApp.Workbooks;
    			oBook = oBooks.Open(strFile, oRien, oRien, del, oRien, oRien, oRien, oRien, oRien, oRien, oRien, oRien, oRien,oRien,oRien);
    			oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oBook.Worksheets[nIndex];
    		}
    Pour la lecture des cellules, j'utilises

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    		public object[,] GetRangeAllType(string LeftUpperCell, string RightBottomCell)
    		{
    			Microsoft.Office.Interop.Excel.Range r = oSheet.get_Range(LeftUpperCell, RightBottomCell);
    			return (object[,])r.Cells.get_Value(XlRangeValueDataType.xlRangeValueDefault);
    		}
    J'utilises cette méthode car Value2 ne me ramenais pas toutes les valeurs des cellules.

  7. #7
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Ben, j'ai fait pareil que toi (fichier csv, get_Value), mais toujours rien à signaler, je garde la précision en type double.

    Essaye peut-être avec un fichier csv que tu génère toi-même, avec uniquement la valeur 200064185399999000 et regarde ce que tu obtiens.

    Sinon, tu peux m'envoyer un exemple de fichier que tu reçois et ton projet Visual Studio, je regarderai.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Points : 89
    Points
    89
    Par défaut
    Bonjour,

    Je profite de ce sujet pour poser ma propre question sur l'Interop Excel (celle que j'utilise est la 11.0 sous Framework 1.1). Je crée un export de données de mon appli dans un fichier xls et j'ai un petit souci : certaines valeurs textes sont égales à des trucs genre "0035", ou "-0565". Excel les interprète comme des nombres, et affiche respectivement "35" et "-565".

    Je souhaiterais donc, au moment de l'écriture de la valeur de la cellule, forcer le format de cette cellule à "Texte". Cela dit, je suis assez paumé dans les membres d'Excel.Range ... Je sens que la solution se trouve ici mais j'ai beau chercher, je ne trouve rien qui me convienne.

    Quelqu'un pourrait-il m'aider?

  9. #9
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Consulte mon article, il te donnera les billes pour faire ce que tu veux avec Excel : Comment piloter Excel avec DotNET.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Points : 89
    Points
    89
    Par défaut
    Bonjour,

    Si je puis me permettre, ton guide n'est qu'une courte introduction de ce qu'il est possible de faire, et je pense maitriser cette partie là. Il se peut que j'ai raté qqchose, mais il ne me semble pas que la réponse à mon problème s'y trouve. Je reformule donc mon problème différemment.

    Le but est d'exporter les lignes de mon ListView dans un fichier Excel. Voici le code correspondant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    private void ExcelRows(Excel._Worksheet Sheet, ref int iRowIndex, ListView lView)
    {
    	foreach (ListViewItem lvItem in lView.Items)
    	{
    		foreach (ColumnHeader clmnHeader in lView.Columns)
    			Sheet.Cells[iRowIndex, clmnHeader.Index + 1] = lvItem.SubItems[clmnHeader.Index].Text;
     
    		iRowIndex++;
    	}
    }
    Le problème est que toute mes valeurs sont du texte. Or, si une valeur de mon ListView est par exemple égale à la chaine de caractère "0565", Excel interprète cela comme un nombre et affiche donc "565". Je voudrais donc, en plus de l'affectation de la valeur de la cellule (Sheet.Cells[i, j] = "valeur"), pouvoir indiquer que la valeur de cette cellule sera forcément du texte, comme lorsque dans Excel je fais clic droit sur la cellule > Format de la cellule > Onglet Nombre > Texte > OK.

    Merci d'avance pour votre aide !

  11. #11
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Citation Envoyé par hobotalker Voir le message
    Si je puis me permettre, ton guide n'est qu'une courte introduction de ce qu'il est possible de faire
    Mais je t'en prie. Je suis d'accord. C'est ce que je dis en conclusion de l'article.
    Citation Envoyé par hobotalker Voir le message
    mais il ne me semble pas que la réponse à mon problème s'y trouve.
    Encore d'accord ! C'est ce que je dis dans mon précédent message :
    Citation Envoyé par Skalp Voir le message
    Consulte mon article, il te donnera les billes pour faire ce que tu veux avec Excel
    Tu n'y trouveras pas la réponse toute faite, mais tu trouveras la méthode pour la trouver.
    Citation Envoyé par hobotalker Voir le message
    Il se peut que j'ai raté qqchose,
    Allez je t'aide, ça t'évitera de te coltiner tout l'article : c'est dans le chapitre VI.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Points : 89
    Points
    89
    Par défaut
    Bonjour et merci de ta réponse.

    En chapitre VI (il y en a deux d'ailleurs !), trois choses :
    - allez voir les Visual Studio Tools si j'y suis : impossible car je suis en Framework 1.1 et la MSDN précise qu'il faut la 2.0 minimum (précisé dans mon post initial)
    - une macro. Impossible, mon fichier de sortie est inexistant au départ.
    - modèle objet Excel.

    Donc je suis sûrement débile profond. Merci quand même pour le petit jeu de piste.

    En espérant trouver ma solution autre part.

  13. #13
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Je ne t'ai pas donné directement la solution jusque là parce que je pense que le mieux pour toi est de connaitre les méthodes afin que tu sois autonome et que tu puisses trouver toi-même la solution lorsque tu voudras faire autre chose en pilotage Excel.
    Apparemment, tu n'as pas l'air curieux de les apprendre, donc je te donne la réponse ci-dessous. Pas de jeu de piste, juste du copier-coller.
    Pour passer le format de la cellule en format "Texte", il faut utiliser la propriété NumberFormat :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    foreach (ColumnHeader clmnHeader in lView.Columns)
    {
        Range maCellule = ((Range)Sheet.Cells[iRowIndex, clmnHeader.Index + 1]);
        maCellule.NumberFormat = "@";
        maCellule.Value2 = lvItem.SubItems[clmnHeader.Index].Text;
    }
    PS : Je ne connaissais pas la solution, j'ai adapté une macro Excel (alors que moi non plus je n'ai pas le fichier de sortie), comme indiqué dans mon article.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Points : 89
    Points
    89
    Par défaut
    Merci beaucoup, désolé du ton agressif du précédent post, mais j'étais vraiment de mauvais poil sur le moment.

    Je saurai donc que dorénavant, VBA et l'Interop se basent sur les mêmes objets et que je peux donc trouver la solution à mes problèmes dans des macros déjà faites.

    Merci et à bientôt !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2007] importation excel : modification du type de données
    Par Phoebe54 dans le forum Modélisation
    Réponses: 1
    Dernier message: 29/04/2010, 16h45
  2. type de données et export excel
    Par mohcultiv dans le forum ASP
    Réponses: 17
    Dernier message: 08/01/2008, 16h03
  3. [Excel] Problème de conversion de type de données
    Par keiserjo dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 25/07/2006, 12h26
  4. [VB.NET][EXCEL 2000] Automation et type de données
    Par Misterburma dans le forum Windows Forms
    Réponses: 4
    Dernier message: 01/02/2006, 15h51
  5. [Delphi + Excel] OleApplication (type de données)
    Par mohamed dans le forum Langage
    Réponses: 2
    Dernier message: 17/10/2005, 14h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo