如何获取ListObject表格的行号而非工作表行号?
获取ListObject表格的最后有效行号(表格内索引)
问题背景
之前已了解通过.Index方法根据列名获取ListObject的列号,现在需要获取表格内的最后有效行号(而非工作表行号)。直接用工作表的.End(xlUp)方法会停在表格边缘,不管底部单元格是否为空,因此写了一个返回工作表行号的函数,但修改为返回表格行号时出错。
原函数(返回工作表行号)
Function TableLastUsedRow(TheTable As ListObject) As Long Dim RowCount As Long, ColCount As Long, TableLastRow As Long With TheTable TableLastRow = .ListRows.Count For ColCount = 1 To .ListColumns.Count If IsEmpty(.DataBodyRange.Cells(TableLastRow, ColCount)) Then RowCount = .DataBodyRange.Cells(TableLastRow, ColCount).End(xlUp).Row If TableLastUsedRow < RowCount Then TableLastUsedRow = RowCount Else TableLastUsedRow = TableLastRow Exit Function End If Next ColCount End With End Function
修改尝试与错误
将获取行号的代码改为:
RowCount = .DataBodyRange.Cells(TableLastRow, ColCount).End(xlUp).ListRow.Index
触发错误:运行时错误'91':对象变量或With块变量未设置
解决方案
错误原因是当整列都为空时,.End(xlUp)会定位到表格的表头行(不属于DataBodyRange),此时该单元格没有ListRow属性,导致报错。以下两种方法可修正问题:
方法1:判断单元格是否在数据区域内
先检查目标单元格是否属于DataBodyRange,再获取ListRow索引:
Function TableLastUsedRow(TheTable As ListObject) As Long Dim RowCount As Long, ColCount As Long, TableLastRow As Long Dim targetCell As Range With TheTable ' 处理空表格情况 If .DataBodyRange Is Nothing Then TableLastUsedRow = 0 Exit Function End If TableLastRow = .ListRows.Count TableLastUsedRow = 0 ' 初始化结果 For ColCount = 1 To .ListColumns.Count Set targetCell = .DataBodyRange.Cells(TableLastRow, ColCount).End(xlUp) ' 仅当单元格在数据区域内时,获取表格行号 If Not Intersect(targetCell, .DataBodyRange) Is Nothing Then RowCount = targetCell.ListRow.Index If RowCount > TableLastUsedRow Then TableLastUsedRow = RowCount End If ' 当前列最后一行非空,直接返回表格总行数 If Not IsEmpty(.DataBodyRange.Cells(TableLastRow, ColCount)) Then TableLastUsedRow = TableLastRow Exit Function End If Next ColCount End With End Function
方法2:通过行号转换计算表格索引
利用表格表头行的位置,将工作表行号转换为表格内的行号,避开ListRow属性的限制:
Function TableLastUsedRow(TheTable As ListObject) As Long Dim RowCount As Long, ColCount As Long, TableLastRow As Long Dim sheetRow As Long With TheTable ' 处理空表格情况 If .DataBodyRange Is Nothing Then TableLastUsedRow = 0 Exit Function End If TableLastRow = .ListRows.Count TableLastUsedRow = 0 ' 初始化结果 For ColCount = 1 To .ListColumns.Count sheetRow = .DataBodyRange.Cells(TableLastRow, ColCount).End(xlUp).Row ' 计算表格内行号:工作表行号 - 表头行号 RowCount = sheetRow - .HeaderRowRange.Row ' 确保行号在有效范围内 If RowCount > TableLastUsedRow And RowCount <= TableLastRow Then TableLastUsedRow = RowCount End If ' 当前列最后一行非空,直接返回表格总行数 If Not IsEmpty(.DataBodyRange.Cells(TableLastRow, ColCount)) Then TableLastUsedRow = TableLastRow Exit Function End If Next ColCount End With End Function
说明
- 两种方法都先处理了空表格的情况,避免无数据行时触发错误。
- 方法1逻辑更贴合ListObject对象模型,方法2通过行号转换的方式兼容性更强,不会因表头行导致属性调用失败。
内容的提问来源于stack exchange,提问作者Forward Ed
相关产品推荐
相关产品推荐

