如何查找具有数据的最后一列?

51

我找到了这个用于查找包含最后数据的行的方法:

ws.Range("A65536").End(xlUp).row

是否有类似的方法可以找到一个工作表中包含数据的最后一列?


2
这种方法可能不适用于拥有超过一百万行的Excel 2007+工作簿。你可能需要使用ws.UsedRange代替。 - ikh
啊,谢谢你告诉我。我不知道。 - Neat Machine
3
@ikh,最好使用ws.Cells(Rows.Count, "A").End(xlUp).row - Reafidy
2
可能是重复的问题:将指定行上的最后一列数据复制到下一个空白列 - Siddharth Rout
7个回答

94

有很多方法可以做到这一点。最可靠的方法是使用find。

Dim rLastCell As Range

Set rLastCell = ws.Cells.Find(What:="*", After:=ws.Cells(1, 1), LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)

MsgBox ("The last used column is: " & rLastCell.Column)

如果你想要找到特定行中使用的最后一列,可以使用以下代码:

Dim lColumn As Long

lColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column

使用已用范围(不太可靠):

Dim lColumn As Long

lColumn = ws.UsedRange.Columns.Count

如果在A列中没有数据,使用“已用范围”将不起作用。查看此处以了解有关“已用范围”的另一个问题:

有关重置“已用范围”的信息,请参见此处


1
+1 阅读。:) 不过建议使用 Application.CountA.Find 一起使用,以避免出现错误。请参考此链接:https://dev59.com/tmfWa4cB1Zd3GeqPdhYt#11883425 - Siddharth Rout
1
谢谢@Sidd,你会在我上面的评论中提供给Ozgrid的链接中找到确切的建议和额外的信息。 - Reafidy
1
@Sidd,这仍然是一个很好的观点,并值得一提。我只是不喜欢发布带有所有错误处理等完整答案,我认为那是为他们做工作,而在我的解释中,这超出了本论坛的范围。 - Reafidy
@brettdj:是的,那也可以使用,但如果您将lastcol存储在变量中,那么我们也可以使用工作表函数。另一个选项是声明一个范围,然后查找适用的列。 :) - Siddharth Rout
@brettdj:我已经将您的建议添加到链接https://dev59.com/tmfWa4cB1Zd3GeqPdhYt#11883425。 - Siddharth Rout
显示剩余3条评论

20

我知道这篇文章比较旧,但是我已经进行了多种测试,它仍然没有让我失望,除非有人能告诉我另外一种情况。

行号

Row = ws.Cells.Find(What:="*", After:=[A1] , SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

列字母

ColumnLetter = Split(ws.Cells.Find(What:="*", After:=[A1], SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Cells.Address(1, 0), "$")(0)

列号

ColumnNumber = ws.Cells.Find(What:="*", After:=[A1], SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column

2
我认为我们可以修改以上@Readify的答案中的UsedRange代码,即使起始列为空或不存在,也能够获取最后使用的列。
因此,将lColumn = ws.UsedRange.Columns.Count修改为lColumn = ws.UsedRange.Column + ws.UsedRange.Columns.Count - 1,将始终给出可靠的结果。

enter image description here

?Sheet1.UsedRange.Column + Sheet1.UsedRange.Columns.Count - 1

上面的代码在立即窗口中输出了 9

2

在激活表格后尝试使用此代码:

Dim J as integer
J = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row

如果您仅使用Cells.SpecialCells(xlCellTypeLastCell).Row,问题将是除非进行“保存文件”操作,否则xlCellTypeLastCell信息不会得到更新。但使用UsedRange将始终实时更新信息。

1
如果您在使用此方法时与列一起使用,则会得到错误的列。 - Stefan Steiger

1

这里有一些可能有用的东西。基于包含数据的行选择整个列,在这种情况下我使用第5行:

Dim lColumn As Long

lColumn = ActiveSheet.Cells(5, Columns.Count).End(xlToLeft).Column
MsgBox ("The last used column is: " & lColumn)

除了更短之外,您的答案与被接受的答案有何不同之处?此外,请避免使用“Select”语句。那真的是一个很糟糕的做法。请参见https://dev59.com/3Ggv5IYBdhLWcg3wSe0f。 - Luuklag
谢谢你对Select语句的提示。我会查看的。干杯! - dapaz

0

如果你的数据从第一行开始,这里有一个简单的选项。

MsgBox "Last Row: " + CStr(Application.WorksheetFunction.CountA(ActiveSheet.Cells(1).EntireRow))

它只是使用CountA来计算整行中具有数据的列数。
这种方法有各种情况下都不会起作用,例如如果您有多个表共享顶部行,但对于一些快速且简单的事情,它非常完美。

0

我已经使用@Reafidy method/answer很长时间了,但今天我遇到了一个问题,即顶行从A1合并到N1,我的函数返回的“最后一列”是1而不是14。

这是我修改后的函数,现在考虑可能合并的单元格:

Public Function Get_lRow(WS As Worksheet) As Integer
 On Error Resume Next
 If Not IsWorksheetEmpty(WS) Then
  Get_lRow = WS.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
  Dim Cell As Range
  For Each Cell In WS.UsedRange
   If Cell.MergeCells Then
    With Cell.MergeArea
     If .Cells(.Cells.Count).Row > Get_lRow Then Get_lRow = .Cells(.Cells.Count).Row
    End With
   End If
  Next Cell
 Else
  Get_lRow = 1
 End If
End Function

Public Function Get_lCol(WS As Worksheet) As Integer
 On Error Resume Next
 If Not IsWorksheetEmpty(WS) Then
  Get_lCol = WS.Cells.Find(What:="*", after:=[A1], SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
  Dim Cell As Range
  For Each Cell In WS.UsedRange
   If Cell.MergeCells Then
    With Cell.MergeArea
     If .Cells(.Cells.Count).Column > Get_lCol Then Get_lCol = .Cells(.Cells.Count).Column
    End With
   End If
  Next Cell
 Else
  Get_lCol = 1
 End If
End Function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接