【问题标题】:How to count the number of rows in excel with data?如何用数据计算excel中的行数?
【发布时间】:2011-06-10 03:25:13
【问题描述】:

A 列有这样的数据(即频繁的空白单元格):

HEADING  <-- this is A1
kfdsl
fdjgnm
fdkj

gdfkj
4353

fdjk  <-- this is A9

我希望能够获得最后一个有数据的单元格的单元格引用。所以在上面的例子中,我想返回:A9

我已经尝试过了,但它在第一个空白单元格处停止(即返回A4

numofrows = destsheet.Range("A2").End(xlDown).Row - 1

【问题讨论】:

标签: .net vb.net excel vba excel-interop


【解决方案1】:

我喜欢这种方式:

ActiveSheet.UsedRange.Rows.Count

列数也可以这样做。对我来说,总是工作。但是,如果您在另一列中有数据,上面的代码也会考虑它们,因为代码正在查找工作表中的所有单元格区域。

【讨论】:

  • 如果您在第 1 行中没有数据,这将给出错误的答案 - 它会给出从第一个单元格到最后一个单元格的行数。如果单元格 a2:a4 中有数据,则此等式将生成 3,而不是 4(使用 Office 2010)。
  • 这种方法可能很危险,因为它可以返回一个有颜色但没有数据的单元格,甚至是一个包含数据但没有正确清理的单元格。
  • 这个答案是错误的,应该删除。 .UsedRange.Rows.Count 返回 UsedRange 中的行数,与最后一条数据的行数不同。因此,如果您的第 1 行和第 2 行是空的,这将返回 2 的错误答案。
  • 如果您想获取已使用范围内的最后一行,请正确执行 - 请参阅newguy's answer。阅读sancho.s answer to know what this returns,如果您需要具有数据(而不是一些剩余格式)和/或在特定列中的行,请参阅my solution
【解决方案2】:

最安全的选择是

Lastrow =  Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row
Lastcol =  Cells.Find("*", [A1], , , xlByColumns, xlPrevious).Column

请勿使用UsedRangeSpecialCells(xlLastCell)End(xlUp)。如果您之前删除了一些行,所有这些方法都可能会给出错误的结果。 Excel 仍会计算这些不可见 单元格。

如果您删除单元格、保存工作簿、关闭并重新打开它,这些方法将再次起作用。

【讨论】:

  • +1 做了一些测试,这似乎是最可靠的,特别是如果您不知道最后一行中的数据是哪一列
  • 这是找到最后一个包含数据的单元格的唯一安全方法。其他方法因隐藏的行/列或没有数据但格式化的单元格或已删除的单元格而失败。
  • 应该在范围上使用Set,并测试该范围是否存在。这假定数据存在于工作表中 - 它会在空白工作表上失败
  • 所以如果我理解正确,我可以使用“lastrow”变量设置第一行开始粘贴新数据“Lastrow = Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row" 例如; "rnum = Lastrow +1"(这将是工作表中的第一个空单元格(?))
【解决方案3】:

这将独立于 Excel 版本(2003、2007、2010)。第一个在一张表中有 65536 行,而后两个有大约一百万行。 Sheet1.Rows.Count 根据版本返回此数字。

numofrows = Sheet1.Range("A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp).Row

或同等但更短的

numofrows = Sheet1.Cells(Sheet1.Rows.Count,1).End(xlUp)

这会从 A 列的底部向上搜索第一个非空单元格,并获取其行号。

如果您的数据在其他列中进一步下降,这也适用。因此,例如,如果您获取示例数据并在单元格 FY4763 中写入一些内容,则上述内容仍将正确返回 9(不是 4763,任何涉及 UsedRange 属性的方法都会错误地返回)。

请注意,实际上,如果您想要单元格引用,您应该只使用以下内容。您不必先获取行号,然后再构建单元格引用。

Set rngLastCell = Sheet1.Range("A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp)

请注意,此方法在某些极端情况下会失败:

  • 最后一行包含数据
  • 最后一行被隐藏或过滤掉

因此,请注意您是否打算将第 1,048,576 行用于这些事情!

【讨论】:

  • 这对我有用 ActiveSheet.UsedRange.Rows.Count 失败(这是我通常使用的)。
  • 您在上面的最佳答案中缺少.Row。新用户可能会对缺少的语句感到困惑。 numofrows = Sheet1.Cells(Sheet1.Rows.Count,1).End(xlUp) 键入时将提供最后使用的单元格的值。 Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp).Row.Row 结尾将按预期提供第 1 列中最后一个单元格的行号。
【解决方案4】:

我用一张长长的测试表比较了所有可能性:

0,140625 秒

lastrow = calcws.Cells.Find("*", [A1], , , xlByColumns, xlPrevious).row

0 秒

iLastRow = calcws.Cells(rows.count, "a").End(xlUp).row

numofrows = calcws.Cells.SpecialCells(xlLastCell).row

0,0078125 秒

lastrow = calcws.UsedRange.rows.count
Do While 1
    If calcws.Cells(lastrow, 1).Value = "" Then
        lastrow = lastrow - 1
    Else
        Exit Do
    End If
Loop

我认为最爱是显而易见的......

【讨论】:

  • +1 - 这是我最喜欢的答案。不偏袒任何一方,只是展示一些选项及其相对效率。应该有更多的赞成票!
  • @Floris:你认为速度是判断各种可能性中哪些应该是最重要的最重要标准吗?而不是哪个可靠地工作? (因为它们并非在所有情况下都返回相同的结果......)
  • @jeanfrancoiscorbett - 显然获得正确答案最重要。我在评论这个答案的公正性 - 速度的客观比较。我喜欢这样,这就是我在回答中试图说的。我可以看到许多可能出错的方式(例如,当最后一行中有值时......)
  • -1 我没有看到其他代码的编译次数像答案,尤其是暗示时间(对于未指定的测试)比实际更重要的代码回答可靠性。最后 numofrows = calcws.Cells.SpecialCells(xlLastCell).row 适用于工作表,而不是 A 列
  • 确实,性能比较是有用的,但在某些情况下所有更快的方法都会返回不正确的结果这一事实并非如此。特别是,第 4 个 sn-p 错误地假设 calcws.UsedRange.rows.count 是最后一行,但如果工作表的前几行是空的,则此假设不成立。
【解决方案5】:

Dim RowNumber As Integer
RowNumber = ActiveSheet.Range("A65536").End(xlUp).Row

在你的情况下它应该返回 #9

【讨论】:

  • +1 ,对于 Excel 2007 及更高版本,请使用 range("A" &amp; activesheet.rows.count).end(xlup).row :)
【解决方案6】:

在另一个网站上发现了这种方法。它适用于新的更大尺寸的 Excel,并且不需要您硬编码最大行数和列数。

iLastRow = Cells(Rows.Count, "a").End(xlUp).Row
iLastCol = Cells(i, Columns.Count).End(xlToLeft).Column

Thanks to mudraker in Melborne, Australia

【讨论】:

    【解决方案7】:

    这些都可以,让 Excel 定义它最后一次看到数据的时间

    numofrows = destsheet.UsedRange.SpecialCells(xlLastCell).row
    
    numofrows = destsheet.Cells.SpecialCells(xlLastCell).row
    

    【讨论】:

    • 这在几个层面上是错误的。您的第一个建议.UsedRange.Rows.count 将返回UsedRange 中的行数,这与最后一条数据的行数 不同.因此,如果您的第 1 行和第 2 行为空,这将返回 2 的错误答案。此外,这包括整个工作表上的最后一个非空单元格,而不仅仅是正在考虑的列。也许这就是OP想要的,但我真的不这么认为;另外,如果有人不小心在“FY54239”单元格中写了一些东西,它真的很容易出错。
    • 您的第二个建议,destsheet.SpecialCells(xlLastCell).row 甚至无法编译,至少在 Excel 2003 中:.SpecialCells 不适用于 Sheet 对象。
    • @Jean...实际上是destsheet.Cells.SpecialCells(xlLastCell).Row ...这绝对是我不包括在内的坏处。首先,.SpecialCells(xlLastCell).Row 也可以应用于UsedRange。我已经用工作代码编辑了我的回复。
    【解决方案8】:
      n = ThisWorkbook.Worksheets(1).Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count
    

    【讨论】:

      【解决方案9】:

      为了更清楚,我想添加一个清晰的示例并运行

                  openFileDialog1.FileName = "Select File"; 
                  openFileDialog1.DefaultExt = ".xls"; 
                  openFileDialog1.Filter = "Excel documents (.xls)|*.xls"; 
      
      
                  DialogResult result = openFileDialog1.ShowDialog();
      
      
                  if (result==DialogResult.OK)
                  {
      
                      string filename = openFileDialog1.FileName;
      
      
                      Excel.Application xlApp;
                      Excel.Workbook xlWorkBook;
                      Excel.Worksheet xlWorkSheet;
                      object misValue = System.Reflection.Missing.Value;
      
                      xlApp = new Excel.Application();
                      xlApp.Visible = false;
                      xlApp.DisplayAlerts = false;
      
      
      
                      xlWorkBook = xlApp.Workbooks.Open(filename, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
      
                      xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
      
                      var numRows = xlWorkSheet.Range["A1"].Offset[xlWorkSheet.Rows.Count - 1, 0].End[Excel.XlDirection.xlUp].Row;
      
                      MessageBox.Show("Number of max row is : "+ numRows.ToString());
      
                      xlWorkBook.Close(true, misValue, misValue);
                      xlApp.Quit();
      
                  }
      

      【讨论】:

        【解决方案10】:

        我更喜欢使用 CurrentRegion 属性,它相当于 Ctrl-*,它将当前范围扩展到其最大的连续数据范围。您从您知道将包含数据的单元格或范围开始,然后将其展开。 UsedRange 属性有时会返回很大的区域,只是因为有人在工作表底部进行了一些格式化。

        Dim Liste As Worksheet    
        Set Liste = wb.Worksheets("B Leistungen (Liste)")     
        Dim longlastrow As Long
        longlastrow = Liste.Range(Liste.Cells(4, 1), Liste.Cells(6, 3)).CurrentRegion.Rows.Count
        

        【讨论】:

        • 这不适用于原始问题,因为数据并非全部连续。
        • 查尔斯,你说得对。在所示的情况下,我的方法确实会失败。
        猜你喜欢
        • 1970-01-01
        • 2011-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-20
        • 1970-01-01
        相关资源
        最近更新 更多