【问题标题】:Range.Value produces different results in VBA and C#Range.Value 在 VBA 和 C# 中产生不同的结果
【发布时间】:2015-09-05 02:48:56
【问题描述】:

我注意到 Range.Value 在 VBA 和 C# 中对日期值产生不同的结果。

例如,如果一个单元格的值为 5/13/1988,NumberFormat 为 d/m/yyyy,在 VBA Range.Value 中将返回“5/13/1988”,而在 C# 中返回“5/13/1988 12: 00:00 AM”

Range.Value2 在两种语言中是相同的 (32276)。

有谁知道为什么 VBA 和 C# 在这种情况下会产生不一致的结果?

请注意,我知道我可以使用 Range.Value2 和 Range.NumberFormat 的组合,然后在 C# 中格式化该值,但我对行为不一致的原因感兴趣。

【问题讨论】:

  • 1899 年 12 月 31 日之后的每一天的日期都是简单的 1,时间是一天的小数部分。 12:00:00 AM(午夜)是 0.0,所以它们表达的内容完全相同。我完全没有发现结果不一致。
  • 同意@Jeeped,Format(cdate("5/13/1988"),"M.DD.YYYY HH:MM:SS")会返回同样的5.13.1988 00:00:00结果,所以没有不一致

标签: c# vba excel vsto


【解决方案1】:

简单。在 Excel 互操作中(您在 VSTO 项目中引用)MS 显然已将 Date 单元格值映射到 .Net DateTime 数据类型。

对他们来说最好的选择,你不会想像 Date .Net 数据类型那样使用(记住 VB 经典只有 Date 数据类型而不是 DateTime)。

在此处了解 excel 如何处理后台数据:https://stackoverflow.com/a/13983731

【讨论】:

    【解决方案2】:

    VB.Net 和 C# 处理方式不同。

    Excel 2013

    Sub Sample()
        MsgBox Sheet1.Range("A1").Value
    End Sub
    


    VB.Net 2013

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        '~~> Opens an existing Workbook. Change path and filename as applicable
        xlWorkBook = xlApp.Workbooks.Open("C:\Users\Siddharth\Desktop\Delete Later\Sample.xlsx")
    
        '~~> Display Excel
        xlApp.Visible = True
        xlWorkSheet = xlWorkBook.Sheets("Sheet1")
    
        MessageBox.Show(xlWorkSheet.Range("A1").Value)
    
        '
        '~~> Rest of the code
        '
    End Sub
    


    C# 2013

    C# 不幸地像你提到的那样处理它。

    您可以这样做以获得所需的结果

        private void button1_Click(object sender, EventArgs e)
        {
            Microsoft.Office.Interop.Excel.Application xlexcel;
            Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
            Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
    
            object misValue = System.Reflection.Missing.Value;
            xlexcel = new Excel.Application();
    
            xlexcel.Visible=true ;
    
            xlWorkBook = xlexcel.Workbooks.Open(
                        "C:\\Users\\Siddharth\\Desktop\\Delete Later\\Sample.xlsx", 
                        0, true, 5, "", "", true, 
                        Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, 
                        "\t", false, false, 0, true, 1, 0);
    
            // Set Sheet 1 as the sheet you want to work with
            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
    
            String cellvalue = xlWorkSheet.Cells[1, 1].Value.ToString("MM/dd/yyyy", 
                               CultureInfo.InvariantCulture);
    
            MessageBox.Show(cellvalue);
    
            //
            //~~> Rest of the code
            //
        }
    

    【讨论】:

    • 你为什么说 VB.NET 和 C# 处理它的方式不同?如果考虑到正确的文化/格式,它们都应该输出完全相同的日期到字符串转换。 VB.NET 和 C# 的行为应该始终相同,因此您的第一个陈述非常具有误导性。
    • 是的,他们应该以相同的方式处理它,但它不像我上面演示的那样:) .Value 两者都给出不同的输出......
    • 实际上我写了我删除的评论的第一个版本(两个显示的消息框没有显示相同的值?)。 MessageBox.Show(xlWorkSheet.Range("A1").Value) (和 VB.NET 版本)是将日期类型(Excel 提供的)转换为字符串的不好方法,只要您没有完全控制权关于正在发生的事情。您应该始终考虑给定的文化和/或格式(例如,下面的 Value.ToString("MM/dd/yyyy"))。为什么你的情况不同?也许两个 VB.NET/C# 项目都有不同的默认文化。如果操作正确,输出将是相同的。
    • 你错过了这里的重点。我没有转换,而是试图展示.Value 在这两种情况下的含义。如果你不 ant 使用MessageBox.Show,请使用快速手表查看区别:)
    • 当您在 .NET 中将日期视为字符串时,会发生日期类型到字符串类型的转换;在这种转换中,文化(和/或日期格式)已被考虑在内。如果您没有明确指定它,给定的语言将采用默认语言(无论它是什么)。因此,要完全控制 .NET 应用程序的任何日期/时间的输入/输出过程,您应该将文化考虑在内,而不是在做什么。在 VB.NET 和 C# 代码中包含上述日期格式,并且行为应该相同。
    【解决方案3】:
    using System.Threading;
    using System.Globalization;
    // Put the following code before InitializeComponent()
    // Sets the culture to US English
    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); 
    // Sets the UI culture too
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-03
      • 1970-01-01
      相关资源
      最近更新 更多