【问题标题】:Programmatically getting the last filled excel row using C#使用 C# 以编程方式获取最后填充的 excel 行
【发布时间】:2011-10-06 13:00:53
【问题描述】:

我正在尝试使用 Microsoft.interop.Excel 库和 C# 以编程方式获取 Excel 工作表的最后一行。我想这样做,因为我负责循环遍历 Excel 电子表格的所有记录并对它们执行某种操作。具体来说,我需要最后一行的实际数字,因为我会将这个数字放入函数中。有人知道怎么做吗?

【问题讨论】:

    标签: c# excel


    【解决方案1】:

    几种方式,

    using Excel = Microsoft.Office.Interop.Excel;
    
    Excel.ApplicationClass excel = new Excel.ApplicationClass();
    Excel.Application app = excel.Application;
    Excel.Range all = app.get_Range("A1:H10", Type.Missing);
    

    Excel.Range last = sheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
    Excel.Range range = sheet.get_Range("A1", last);
    
    int lastUsedRow = last.Row;
    int lastUsedColumn = last.Column;
    

    【讨论】:

    • 不确定第一个选项如何工作......但第二个看起来很有趣。如何将其转换为 int 值?
    • 我编辑了我的代码,我还没有测试过该代码,但希望这能让您了解您想要实现的目标。
    • 此答案为您提供了工作表 UsedRange 中的最后一个单元格。但是,问题是 UsedRange 永远不会收缩。如果 A1 和 AA100 中有值,那么删除 AA100 的内容,UsedRange 仍然是 A1:AA100。 AA100 仍将被视为最后一个单元格。
    • 完美的解决方案,正是我所需要的
    • @CtrlDot 是一个非常有效的点,UsedRange 不能按预期工作,不能信任 xlCellTypeLastCell 方法。
    【解决方案2】:

    这是 Excel 中的常见问题。

    这是一些 C# 代码:

    // Find the last real row
    nInLastRow = oSheet.Cells.Find("*",System.Reflection.Missing.Value, 
    System.Reflection.Missing.Value, System.Reflection.Missing.Value,    Excel.XlSearchOrder.xlByRows,Excel.XlSearchDirection.xlPrevious, false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Row;
    
    // Find the last real column
    nInLastCol = oSheet.Cells.Find("*", System.Reflection.Missing.Value,     System.Reflection.Missing.Value,System.Reflection.Missing.Value, Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlPrevious,    false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Column;
    

    找到here

    或使用SpecialCells

    Excel.Range last = sheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
    Excel.Range range = sheet.get_Range("A1", last);
    

    [编辑] 类似主题:

    【讨论】:

    • 这行得通,我一直在努力获得正确的行。
    • 方法 1 有效。方法 2 - 不可靠的已删除已用单元格被 UsedRange 和“xlCellTypeLastCell”“标记”为“脏”,并且仍然认为这些单元格仍在使用中并将空单元格报告为“已使用”
    • 请注意,如果存在过滤器或其他行隐藏效果会混淆实际的最后一行数据,您可能会得到错误的答案。下面的答案涵盖了这一点,但您也可以使用来自here 的答案。我使用excelWorksheet.AutoFilter.ShowAllData() 来保留过滤器的存在,同时释放应用的过滤器,以便显示所有行。
    【解决方案3】:

    Pryank's answer 是最适合我的。我在最后添加了一点 (.Row),所以我不只是返回 range,而是返回 integer

    int lastRow = wkSheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing).Row;
    

    【讨论】:

    • 拯救了我的一天!谢谢!
    • 不可靠的已删除的已用单元格被 UsedRange “标记”,“xlCellTypeLastCell”被标记为“脏”,并且仍然认为这些单元格仍在使用中,并将空单元格报告为“已使用”
    【解决方案4】:

    我可以让它在所有场景中工作的唯一方法(受保护的工作表除外):

    它支持:

    • 扫描隐藏的行/列

    • 忽略没有数据/公式的格式化单元格

    代码:

    // Unhide All Cells and clear formats
    sheet.Columns.ClearFormats();
    sheet.Rows.ClearFormats();
    
    // Detect Last used Row - Ignore cells that contains formulas that result in blank values
    int lastRowIgnoreFormulas = sheet.Cells.Find(
                    "*",
                    System.Reflection.Missing.Value,
                    InteropExcel.XlFindLookIn.xlValues,
                    InteropExcel.XlLookAt.xlWhole,
                    InteropExcel.XlSearchOrder.xlByRows,
                    InteropExcel.XlSearchDirection.xlPrevious,
                    false,
                    System.Reflection.Missing.Value,
                    System.Reflection.Missing.Value).Row;
    // Detect Last Used Column  - Ignore cells that contains formulas that result in blank values
    int lastColIgnoreFormulas = sheet.Cells.Find(
                    "*",
                    System.Reflection.Missing.Value,
                    System.Reflection.Missing.Value,
                    System.Reflection.Missing.Value,
                    InteropExcel.XlSearchOrder.xlByColumns,
                    InteropExcel.XlSearchDirection.xlPrevious,
                    false,
                    System.Reflection.Missing.Value,
                    System.Reflection.Missing.Value).Column;
    
    // Detect Last used Row / Column - Including cells that contains formulas that result in blank values
    int lastColIncludeFormulas = sheet.UsedRange.Columns.Count;
    int lastColIncludeFormulas = sheet.UsedRange.Rows.Count;
    

    【讨论】:

    • 绝妙的答案(也是唯一对我有用的答案)。
    【解决方案5】:

    对于涉及 Excel 对象模型的问题,通常先在 VBA 中尝试比较容易,然后翻译成 C# 相当简单。

    在这种情况下,在 VBA 中执行此操作的一种方法是:

    Worksheet.UsedRange.Row + Worksheet.UsedRange.Rows.Count - 1
    

    【讨论】:

      【解决方案6】:

      ActiveSheet.UsedRange.Value 返回[row, column] 的二维对象数组。检查两个维度的长度将提供LastRow 索引和LastColumn 索引。下面的示例使用 C#。

      Excel.Worksheet activeSheet;
      Excel.Range activeRange;
      
      public virtual object[,] RangeArray 
      {
          get { return ActiveRange.Value; }
      }
      
      public virtual int ColumnCount 
      {
          get { return RangeArray.GetLength(1); }
      }
      
      public virtual int RowCount
      {
          get { return RangeArray.GetLength(0); }
      }
      
      public virtual int LastRow 
      {
          get { return RowCount; }
      }
      

      【讨论】:

        【解决方案7】:

        当可能存在空单元格时,此问题会更加严重。但是即使只填充了一个值,您也必须读取一行。当有很多未填充的单元格时可能需要一段时间,但如果输入接近正确,则速度相当快。

        我的解决方案会忽略完全空的行并返回最长列的行数:

        private static int GetLastRow(Worksheet worksheet)
            {
                int lastUsedRow = 1;
                Range range = worksheet.UsedRange;
                for (int i = 1; i < range.Columns.Count; i++)
                {
                    int lastRow = range.Rows.Count;
                    for (int j = range.Rows.Count; j > 0; j--)
                    {
                        if (lastUsedRow < lastRow)
                        {
                            lastRow = j;
                            if (!String.IsNullOrWhiteSpace(Convert.ToString((worksheet.Cells[j, i] as Range).Value)))
                            {
                                if (lastUsedRow < lastRow)
                                    lastUsedRow = lastRow;
                                if (lastUsedRow == range.Rows.Count)
                                    return lastUsedRow - 1;
                                break;
                            }
                        }
                        else
                            break;
                    }
                }
                return lastUsedRow;
            }
        

        【讨论】:

          【解决方案8】:

          对于那些使用SpecialCells方法的人,(我不确定其他人),请注意,如果您的最后一个单元格被合并,您将无法获取最后一行和列号使用 Range.Row 和 Range.Column 将最后一行和最后一列作为数字。 您需要首先 Unmerge 您的范围,然后再次获取最后一个单元格。 我花了很多钱。

          private int[] GetLastRowCol(Ex.Worksheet ws)
              {
                  Ex.Range last = ws.Cells.SpecialCells(Ex.XlCellType.xlCellTypeLastCell, Type.Missing);
                  bool isMerged = (bool)last.MergeCells;
                  if (isMerged)
                  {
                      last.UnMerge();
                      last = ws.Cells.SpecialCells(Ex.XlCellType.xlCellTypeLastCell, Type.Missing);
                  }
                  return new int[2] { last.Row, last.Column };
              }
          

          【讨论】:

            【解决方案9】:

            如前所述,上述技术(xlCellTypeLastCell 等)并不总能提供预期的结果。尽管向下迭代检查值的列并不困难,但有时您可能会发现有空单元格或行包含要在后续行中考虑的数据。直接使用 Excel 时,找到最后一行的一个好方法是按几次 CTRL + 向下箭头(对于 XLSX 工作表,您将在第 1048576 行结束),然后按 CTRL + 向上箭头,这将选择最后一行填充单元格。如果您在录制宏时在 Excel 中执行此操作,您将获得复制此代码的代码,然后只需使用 Microsoft.Office.Interop.Excel 库为 C# 调整它。例如:

                private int GetLastRow()
                {
                    Excel.Application ExcelApp;
                    ExcelApp = new Excel.Application();
            
                    ExcelApp.Selection.End(Excel.XlDirection.xlDown).Select();
                    ExcelApp.Selection.End(Excel.XlDirection.xlDown).Select();
                    ExcelApp.Selection.End(Excel.XlDirection.xlDown).Select();
            
                    ExcelApp.Selection.End(Excel.XlDirection.xlUp).Select();
            
                    return ExcelApp.ActiveCell.Row;
                }
            

            这可能不是最优雅的解决方案(我想您可以在使用 XlUp 之前直接导航到电子表格中的最后一行),但它似乎更可靠。

            【讨论】:

              【解决方案10】:

              正如 CtrlDot 和 Leo Guardian 所说,这种方法不是很准确,有些文件的格式会影响“SpecialCells”。

              所以我使用了它加上 While 的组合。

              Range last = sheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);
              Range range = sheet.get_Range("A1", last);
              int lastrow = last.Row;
              // Complement to confirm that the last row is the last
              string textCell= "Existe";
              while (textCell != null)
              {
               lastrow++;
               textCell = sheet.Cells[lastrow + 1, 1].Value;
              }
                              
                              
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-09-13
                • 1970-01-01
                • 2017-02-04
                • 2012-02-23
                • 2011-06-27
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多