将Excel单元格值设置为十进制C#。.NET2和.NET4之间的差异

将Excel单元格值设置为十进制C#。.NET2和.NET4之间的差异,c#,.net,excel,C#,.net,Excel,我有一段代码(这是真实代码的简化版本),可以打开excel并设置单元格的值。请注意,我在意大利,我们使用,而不是来分隔小数位数。这意味着我在代码中使用了12.5,但是ToString()对这个数字的结果是“12,5”,Excel也显示了12,5 using Xls = Microsoft.Office.Interop.Excel; public class ExcelTest { public static void Test { object hmissing

我有一段代码(这是真实代码的简化版本),可以打开excel并设置单元格的值。请注意,我在意大利,我们使用而不是来分隔小数位数。这意味着我在代码中使用了12.5,但是
ToString()
对这个数字的结果是“12,5”,Excel也显示了12,5

using Xls = Microsoft.Office.Interop.Excel;

public class ExcelTest
{
    public static void Test
    {
        object hmissing = System.Reflection.Missing.Value;
        // create an instance of Excel and make it visible            
        Xls.Application anApp = new Xls.ApplicationClass();
        anApp.Visible = true;
        // add an empty workbook
        Xls.Workbooks wbks = anApp.Workbooks;
        wbks.Add(hmissing);
        Marshal.ReleaseComObject(wbks);
        // set the value of the first cell
        Decimal d = 12.5m;
        Xls.Range aRange = anApp.get_Range("A1", hmissing);
        aRange.set_Value(Xls.XlRangeValueDataType.xlRangeValueDefault, d.ToString());
        Marshal.ReleaseComObject(aRange);
    }
}
使用.NET2多年来一切都很好,但当我尝试切换到.NET4时,Excel警告我数字已存储为文本

请注意,我知道简单地避免调用ToString()可以解决问题,但在实际情况中,我处理的是一个遗留应用程序,它希望在excel中存储多种类型的数据,包括基类型和用户定义的数据,以及ToString()是所有这些类型上唯一可用的方法,可以在Excel中提供所需的结果,而无需检查类型并决定传递什么来设置_值

因此,我不是问如何修改我的代码以使其工作。我只是想理解为什么在两个版本的框架中行为是不同的。这一点非常重要,因为我希望在用户发现有问题之前修改代码。

试试以下方法:

        Excel.Application excel = new Excel.Application();
        Excel.Workbook workbook = excel.Workbooks.Open(@"c:\test.xls", Missing.Value, Missing.Value,
                                                       Missing.Value, Missing.Value, Missing.Value,
                                                       Missing.Value, Missing.Value, Missing.Value,
                                                       Missing.Value, Missing.Value, Missing.Value, false,
                                                       Missing.Value, Missing.Value);

        Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];

        decimal dec = 12.5m;
        worksheet.get_Range("A1").Value = dec;

        DateTime date = DateTime.Now.Date;
        worksheet.get_Range("A2").Value = date;

        string str = "Hello";
        worksheet.get_Range("A3").Value = str;

        Marshal.FinalReleaseComObject(worksheet);
        workbook.Save();
        workbook.Close(false, Type.Missing, Type.Missing);
        Marshal.FinalReleaseComObject(workbook);
        excel.Quit();
        Marshal.FinalReleaseComObject(excel);
“ToString”方法的输出不是一成不变的,它取决于线程正在运行的当前文化信息。 如果您使用另一种语言包在pc上运行该程序,则输出可能会更改。 另一个原因可能是当前线程被设置为代码中其他地方的某个CultureInfo

请尝试以下示例

static void Main(string[] args)
{
        decimal d = 12.56m;
        // Different thread cultureinfo
        Thread.CurrentThread.CurrentCulture = 
            new System.Globalization.CultureInfo("de-DE");
        Console.WriteLine(d);
        Thread.CurrentThread.CurrentCulture = 
            new System.Globalization.CultureInfo("en-US");
        Console.WriteLine(d);

        Console.WriteLine(d.ToString(
            new System.Globalization.CultureInfo("de-DE").NumberFormat));
        Console.WriteLine(d.ToString(
            new System.Globalization.CultureInfo("en-US").NumberFormat));
        Console.Read();
}

我不知道为什么.NET2和.NET4之间有区别,但是你使用的是哪个版本的Excel?您确定这不仅仅是Excel版本的差异吗?它似乎不依赖于Excel版本。我用Excel2003和Excel2010进行了尝试,得到了相同的结果。我希望我知道答案,但我知道.NET4在互操作工作原理方面做了很多工作。我找不到一个明确的解释,但是关于互操作的突破性变化提出了一些关于您列出的代码的有趣点:即,互操作类型的嵌入和可选参数的处理方式似乎暗示了您所看到的情况。请注意,我不是问如何修改ny代码以消除这个问题。我只是想知道为什么这两个版本的框架之间存在如此大的差异,以便能够在客户发现其他可能的错误之前发现它们。我使用不同版本的框架在同一台机器上运行示例(使用完全相同的cultureinfo)。此外,ToString()的结果与我期望的结果完全相同。