【问题标题】:Capturing Time Values from an Excel Cell从 Excel 单元格中捕获时间值
【发布时间】:2011-03-13 14:37:54
【问题描述】:

我正在编写一个 Excel 应用程序,它将读取和写入 Excel 文件中的指定值,并将它们显示给用户。但是,当我尝试从具有Number Format 或类型为'hh:min' (Hour:Min) 的函数的单元格中读取时,我无法获得我想要的值。

这是我的代码...

ws[dateTimePicker1.Value.Day + 1].get_Range("F" + i.ToString(), Type.Missing);
    if (range.Value2 != null)  
        val += " - " + range.Value2.ToString();   //Sets FXX to val
    lbHK1.Items.Add(val);

在哪里...

  • ws = 我的工作表
  • dateTimePicker1 = 我的日期时间选择器,它可以帮助我决定打开哪个文件
  • i = 是一个整数,可以帮助我确定该单元格的行号
  • range = 是从 Microsoft.Office.Interop.Excel.Range 创建的对象

在我的示例中,当i = 11 时,F11 是包含时间值06:30 的单元格(在 Excel 中,fx : 06:30:00)。但是,当我尝试获取该值时,它会返回 double 类型,例如 0.263888888888889

我怎样才能得到正确格式化的值,因为它在 Excel 中显示,而不是无意义的双精度值?

【问题讨论】:

    标签: c# excel cell-formatting


    【解决方案1】:

    在处理 Excel 日期时,日期可以存储为日期的字符串表示形式,也可以是 OA date(OLE 自动化日期)。我发现在解析 Excel 日期时检查这两种类型是最安全的方法。

    这是我为转换编写的扩展方法:

    /// <summary>
    /// Sometimes the date from Excel is a string, other times it is an OA Date:
    /// Excel stores date values as a Double representing the number of days from January 1, 1900.
    /// Need to use the FromOADate method which takes a Double and converts to a Date.
    /// OA = OLE Automation compatible.
    /// </summary>
    /// <param name="date">a string to parse into a date</param>
    /// <returns>a DateTime value; if the string could not be parsed, returns DateTime.MinValue</returns>
    public static DateTime ParseExcelDate( this string date )
    {
        DateTime dt;
        if( DateTime.TryParse( date, out dt ) )
        {
            return dt;
        }
    
        double oaDate;
        if( double.TryParse( date, out oaDate ) )
        {
            return DateTime.FromOADate( oaDate );
        }
    
        return DateTime.MinValue;
    }
    

    在您的示例中,用法是:

    TimeSpan time = f11Value.ParseExcelDate().TimeOfDay;
    

    【讨论】:

      【解决方案2】:

      Excel 在内部将时间存储为包含 24 小时制小数部分的双精度:因此上午 6:30 为 0.2708333

      【讨论】:

      • 这很有趣,因为当我通过 GetType() 方法获取值类型时,它说它是双值类型。无论哪种方式,那么我将如何解决这个问题呢?你能在这里输入一个简单的代码吗?
      【解决方案3】:

      Excel 以一天的分数存储时间,12:00 将存储为 0.5,因为 12/24 = 1/2 = 0.5

      要获得小时数,您必须将 excel 时间乘以 24,然后将结果四舍五入为整数。

      要获得分钟数(因为一天有 1440 分钟),您必须将该值乘以 1440,这将得出自 00:00 以来经过的分钟数,您需要除以 60 并计算余数以分钟为单位获取时间的操作。

      这是一个sn-p:

      string parseExcelHour(string cellInput){
      
          double excelHour = 0;
      
          try{
              excelHour = Double.Parse(cellInput);
          }catch { }
      
          int hour = (int) (excelHour * 24);// with the int cast you get only an integer.
          int min = (int) (excelHour * 1440 % 60); //mod (%) takes only the remainder and then the cast to int will round the number
      
          return (hour < 10? "0":"") + hour + ":" + (min < 10? "0":"") + min; //will print HH:mm
      }
      

      【讨论】:

      • 努力工作,在某些情况下有效。不幸的是,它并没有正确解析所有时间。我有 17:05 回来为 17:4
      • @Shumii 由于浮点和双精度运算不精确,您可能会丢失一些数据并得到 29.999999 分钟而不是 30 分钟。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多