2009-09-01 9 views
1

J'essaye d'écrire dans une feuille de calcul Excel 2003 en utilisant C# 3.5. Cependant, je ne parviens pas à faire fonctionner correctement cela dans les différents pays. Les paramètres du pays sont anglais ou allemand. Ces deux paramètres ont des paramètres décimaux et des milliers différents. Tout fonctionne correctement, sauf si un utilisateur a modifié les séparateurs décimal et milliers dans les paramètres internationaux de l'écran Options. Quelqu'un peut-il aider car je sens que je ne peux plus voir le bois pour les arbres et qu'il me manque quelque chose d'évident.C# - Problème de formatage du nombre Excel avec les paramètres internationaux

Résumé:

données extraites d'une base de données d'accès. Lecture par application C# et écrite dans une feuille de calcul Excel.

Version Excel 2003 Les machines sont anglaises ou allemandes. Il est possible que les séparateurs décimaux et les séparateurs de milliers aient été modifiés dans les options Paramètres internationaux dans Excel - C'est là que le problème se produit.

comportement observé:
setup anglais avec les options par défaut -> International - comme prévu
configuration allemande avec les options par défaut -> International- comme prévu

setup anglais avec séparateur décimal changé "", séparateur de milliers réglé sur "." et Séparateurs système décochés dans Options -> International - Données incorrectes. Voir les lignes marquées d'un astérisque.

données Excel

3706888,0300 3706888,03
2587033,8000 2587033,8
2081071,1800 2081071,18
9030160,3333 90.301.603.333 **
42470,9842 424.709.842 **
4465546,2800 4465546,28
1436037,3200 1436037,32
111650,0000 111650
2567007.0833 25.670.070.833 **

J'ai attcahed l'exemple de code pour démontrer ce comportement. Si quelqu'un peut me montrer ce que je fais mal, ce serait très apprécié. Pour exécuter cet exemple de code, créez simplement une nouvelle application Windows Forms et publiez le code ci-dessous dans Form1.cs. Vous devrez également ajouter une référence à Microsoft.Office.Interop.Excel.

Merci beaucoup

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using Microsoft.Office.Interop.Excel; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Globalization; 


namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     public void ExportDTToExcel() 
     { 

      Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); 
      app.Visible = true; 
      Workbook wb = app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet); 
      Worksheet ws = (Worksheet)wb.ActiveSheet; 


      string culture = System.Threading.Thread.CurrentThread.CurrentCulture.ToString();//"en-GB"; 
      CultureInfo ci = new CultureInfo(culture); 

      string excelGroupSeparator = app.ThousandsSeparator.ToString(); 
      string excelDecimalSeparator = app.DecimalSeparator.ToString(); 
      bool systemseparators = app.UseSystemSeparators ; 
      if (app.UseSystemSeparators == false) 
      { 
       app.DecimalSeparator = ci.NumberFormat.NumberDecimalSeparator; 
       app.ThousandsSeparator = ci.NumberFormat.NumberGroupSeparator; 
       //ci.NumberFormat.NumberDecimalSeparator = app.DecimalSeparator; 
       //ci.NumberFormat.NumberGroupSeparator = app.ThousandsSeparator; 
      } 
      //app.DecimalSeparator = ci.NumberFormat.NumberDecimalSeparator; 
      //app.ThousandsSeparator = ci.NumberFormat.NumberGroupSeparator; 


      app.UseSystemSeparators = true; 


      // Content. 

      try 
      { 
       SetCellValue("3706888.0300", ws, 0, 0, ci); 
       SetCellValue("2587033.8000", ws, 1, 0, ci); 
       SetCellValue("2081071.1800", ws, 2, 0, ci); 
       SetCellValue("9030160.3333", ws, 3, 0, ci); 
       SetCellValue("42470.9842", ws, 4, 0, ci); 
       SetCellValue("4465546.2800", ws, 5, 0, ci); 
       SetCellValue("1436037.3200", ws, 6, 0, ci); 
       SetCellValue("111650.0000", ws, 7, 0, ci); 
       SetCellValue("2567007.0833", ws, 8, 0, ci); 

      } 
      catch (Exception e) 
      { 


        MessageBox.Show(e.Message); 

      } 

      //wb.SaveAs(Filepath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 
      //wb.Close(false, Type.Missing, false); 
      app.DecimalSeparator = excelDecimalSeparator; 
      app.ThousandsSeparator = excelGroupSeparator; 
      app.UseSystemSeparators = systemseparators; 
      //app.Quit(); 
      Marshal.ReleaseComObject(app); 
      Marshal.ReleaseComObject(wb); 
      Marshal.ReleaseComObject(ws); 
      app = null; 
      wb = null; 
      ws = null; 


     } 

     private static void SetCellValue(string data, Worksheet ws,int row, int col, CultureInfo ci) 
     { 


       double val; 
       try 
       { 
        val = Convert.ToDouble(data); 
        Console.WriteLine(val); 

       } 
       catch (Exception e) 
       { 

        //Util.Log("Null Value ignored.", LogType.ERROR); 
        return; 
       } 

       try 
       { 
        string s = val.ToString(); 
        ws.Cells[row + 2 , col + 1] = s; 

        //Util.Log("S:" + s, LogType.ERROR); 
       } 
       catch 
       { 
        //Util.Log("Null Value ignored.", LogType.ERROR); 
       } 
      } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      this.Cursor = Cursors.WaitCursor; 
      ExportDTToExcel(); 
      this.Cursor = Cursors.Default; 
     } 
     } 
    } 
+0

Je viens de scanner votre code et je me demandais pourquoi vous avez 'CultureInfo ci' comme entrée pour la méthode' SetCellValue' parce que vous ne l'utilisez pas ... –

Répondre

1

This KB article, et deux autres articles KB relie à, décrire quelques-uns des problèmes de localisation, vous pouvez frapper lors de l'automatisation Excel de .NET.

Il peut aider à expliquer votre problème

+0

Merci Joe. L'article que vous avez lié incluait quelque chose que j'avais négligé initialement. Il semble que (en conjonction avec une suggestion ci-dessous de Chris) je devais déclarer les objets Workbook et Worksheet après avoir défini CultureInfo. –

3

Je n'ai pas exécuter votre code, juste scannée ...

Premier problème potentiel: Vous regardez UseSystemSeparators, puis définir le DecimalSeparaor et ThousandsSeparator.

 if (app.UseSystemSeparators == false) 
     { 
      app.DecimalSeparator = ci.NumberFormat.NumberDecimalSeparator; 
      app.ThousandsSeparator = ci.NumberFormat.NumberGroupSeparator; 
     } 

Puis juste après, vous tournez sur SystemSeparators, de sorte que le code ci-dessus ne fait rien puisque vous tournez le système seperators sur.

 app.UseSystemSeparators = true; 

problème potentiel Deuxième/suggestion: Lorsque vous définissez la valeur de la cellule, elle a mis en valeur double au lieu de chaîne, laissez Excel formater le numéro pour vous.

+0

Merci Chris. J'ai nettoyé le code et je l'ai maintenant travaillé en ayant enlevé certaines des lignes inutiles. Je l'ai incorporé dans mon code et l'équipe de test lui donne maintenant un bon bash. Je posterai la version de travail ci-dessous. C# n'est pas ma langue maternelle donc, bien que le code fonctionne, je suis toujours ouvert aux moyens de l'améliorer. –

1

Merci à Chris et Joe, j'ai finalement obtenu le code pour travailler comme vous le souhaitez.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using Microsoft.Office.Interop.Excel; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Globalization; 


namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     public void ExportDTToExcel() 
     { 

      Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); 
      app.Visible = true; 

      string culture = System.Threading.Thread.CurrentThread.CurrentCulture.ToString();//"en-GB"; 
      CultureInfo ci = new CultureInfo(culture); 

      bool systemseparators = app.UseSystemSeparators ; 
      if (app.UseSystemSeparators == false) 
      { 

       app.UseSystemSeparators = true; 

      } 

      // Content. 
      Workbook wb = app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet); 
      Worksheet ws = (Worksheet)wb.ActiveSheet;    
      try 
      { 
       SetCellValue("3706888.0300", ws, 0, 0, ci); 
       SetCellValue("2587033.8000", ws, 1, 0, ci); 
       SetCellValue("2081071.1800", ws, 2, 0, ci); 
       SetCellValue("9030160.3333", ws, 3, 0, ci); 
       SetCellValue("42470.9842", ws, 4, 0, ci); 
       SetCellValue("4465546.2800", ws, 5, 0, ci); 
       SetCellValue("1436037.3200", ws, 6, 0, ci); 
       SetCellValue("111650.0000", ws, 7, 0, ci); 
       SetCellValue("2567007.0833", ws, 8, 0, ci); 

      } 
      catch (Exception e) 
      { 


        MessageBox.Show(e.Message); 

      } 

      app.UseSystemSeparators = systemseparators; 
      Marshal.ReleaseComObject(app); 
      Marshal.ReleaseComObject(wb); 
      Marshal.ReleaseComObject(ws); 
      app = null; 
      wb = null; 
      ws = null; 
     } 

     private static void SetCellValue(string data, Worksheet ws,int row, int col, CultureInfo ci) 
     { 
       double val; 
       try 
       { 
        val = Convert.ToDouble(data); 
        Console.WriteLine(val); 
       } 
       catch (Exception e) 
       { 

        //Util.Log("Null Value ignored.", LogType.ERROR); 
        return; 
       } 

       try 
       { 
        string s = val.ToString(); 
        ws.Cells[row + 2 , col + 1] = s; 

        //Util.Log("S:" + s, LogType.ERROR); 
       } 
       catch 
       { 
        //Util.Log("Null Value ignored.", LogType.ERROR); 
       } 
      } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      this.Cursor = Cursors.WaitCursor; 
      ExportDTToExcel(); 
      this.Cursor = Cursors.Default; 
     } 


    } 
} 
1

Excel utilisé sur COM a plusieurs restrictions les plus importantes à respecter sont les suivantes:

  • Utilisez la culture en-US (LCID bug)
  • Appel toutes les méthodes d'un et le même fil (mettre à la bonne culture "en-US")

Ensuite, vous allez vous débarrasser de la plupart des plantages sporadiques concernant l'automatisation Excel & localisation .

Questions connexes