问题:需要查找sheet中一个区域(a1所在range)的右下角单元格
-
目标:查找从range("A1")单元格开始的这个区域的右下角的单元格
- 应该是 cells(102,4) ,但实际上不同方法查出的结果可能会不同
-
数据表(后面的代码基于这个例子),表里存这样3个不连续的数据区域。
方法1:使用 range().specialcells(xlcelltypelasetcell)
- 特点:简洁,快
- 范围:specialcells会在全sheet查找
- a1随意设定即可,是sheet中的任一单元格,或者用 usedrange() 也是一样
- 语法
- range().specialcells(xlcelltypelasetcell)
- cells().specialcells(xlcelltypelasetcell)
- activesheet.usedrange.specialcells(xlcelltypelasetcell)
- 局限性
- 目标是查全表的所有区域,很简洁好用
- 目标是查某个区域,而sheet只有一个区域时,和这个方法很方便很快
- 目标是查某个区域,而 sheet 中不只这一个唯一区域时,这个方法不好用。
Sub test81()
'取某个区域最后一个单元格的方法(右下角的cell)
m1 = Range("a1").SpecialCells(xlCellTypeLastCell)
Debug.Print Range("a1").SpecialCells(xlCellTypeLastCell).Address
Debug.Print Range("a1").SpecialCells(xlCellTypeLastCell).Row
Debug.Print Range("a1").SpecialCells(xlCellTypeLastCell).Column
Debug.Print "cells(" & Range("a1").SpecialCells(xlCellTypeLastCell).Row & "," & Cells(1, 1).SpecialCells(xlCellTypeLastCell).Column & ")"
End Sub
看查找结果,当前sheet里查到的不是 range("a1") 这个区域右下角的单元格
方法2 使用 usedrange().address
- 用 usedrange 也可以类方法1的方式查
- activesheet.usedrange().specialcells()
- 直接取的 usedrange().address
- 一般是 $A$1:$J$102 ,后面那个就是右下角的单元格cell
- 取右下角cell 就是 Range(Split(ActiveSheet.UsedRange.Address, ":")(1)).Address ---$J$102
- 局限性:因为usedrange 默认也是sheet的全部使用的区域,所以也会查到多个区域
Sub test85()
'用usedrange().specialcells() 也一样
Debug.Print ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
Debug.Print ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Column
Debug.Print ActiveSheet.UsedRange.Address
Debug.Print Range(Split(ActiveSheet.UsedRange.Address, ":")(1)).Address
End Sub
查到的不是 range("a1") 这个区域右下角的单元格
方法3:从区域外部,用缩小范围的方法去查 Range("a65536").End(xlUp).Row
- Range("a65536").End(xlUp)适合查整个sheet的某一列的最后一个有值的单元格。
- 用缩小范围的方法去查
- 从尽量大的行列,往回找,可以找到最后一个有值区域,应对 range 中间有空行空列,不连续的情况
- 比较实用于,查单列,中间还有空行的情况
- 下面这种方法,可以方便的查一列的最后一个单元格cells() 中间有空格也无所谓
- Range("a65536").End(xlUp).Row
- 局限性
- 如果 sheet上只有1个区域,没有问题
- 如果 sheet上有多个区域,
- 在于选择的起始单元格,所在那行,那列,如果没有其他区域就没问题
- 如果选择的起始单元格,所在那行,那列,如果没有其他区域就没问题就有问题
Sub test82() '用缩小范围的方法去查
Debug.Print "这样查就会超越1个区域"
m2 = Cells(Range("a65536").End(xlUp).Row, Cells(1, 9999).End(xlToLeft).Column)
Debug.Print Range("a65536").End(xlUp).Row
Debug.Print Cells(1, 9999).End(xlToLeft).Column
Debug.Print "cells(" & Range("a65536").End(xlUp).Row & "," & Cells(1, 9999).End(xlToLeft).Column & ")"
Debug.Print
Debug.Print "这样查就OK"
m3 = Cells(Range("a65536").End(xlUp).Row, Cells(10, 9999).End(xlToLeft).Column)
Debug.Print Range("a65536").End(xlUp).Row
Debug.Print Cells(10, 9999).End(xlToLeft).Column
Debug.Print "cells(" & Range("a65536").End(xlUp).Row & "," & Cells(10, 9999).End(xlToLeft).Column & ")"
End Sub
注意方法3 尽量不要全表 max_row max_column 范围去查,注意效率
- 如何需要取最大行数或列数,实用中尽量别用全表的 max_row max_column
- 如果非要强调尽量大的行,列,非空区域准确性,方法2的补充
- 找当前sheet的最大行列数,用空行空列可查
- 或者 rows.count 和 columns.count
- max_row max_column都很大,一般不要在这么大的范围内循环查找内容,一般情况用不到"
- 找到空行,空列,可以定位当前版本EXCEL的最大行数,列数"
Sub test83()
'如何需要取最大行数或列数,实用中尽量别用全表的 max_row max_column
Debug.Print "方法1"
Debug.Print "max_row= " & Range("e1").End(xlDown).Row
Debug.Print "max_column= " & Cells(105, 1).End(xlToRight).Column
Debug.Print "方法2"
Debug.Print "不用range(""a65536"") 这种极大值的方法,用rows.count"
Debug.Print "这种方法适合取一个区域内的下限"
Debug.Print Cells(Rows.Count, Columns.Count)
Debug.Print Rows.Count
Debug.Print Columns.Count
Debug.Print "方法3---这种缩小范围的思路一般情况更可取,除非要求特别准,或其他要求"
Debug.Print Range("a65536").End(xlUp).Row
End Sub
方法4 快速定位一个range区域内的右下角 cell
- 方法
- Range("a1").End(xlDown).End(xlToRight)
- 查一个连续区域内的边界,在区域内,用这些即可
- end(xlup)
- end(xldown)
- end(xltoleft)
- end(xltorigjt)
- 查一个连续区域内部
- 局限性:
- 如果目标要查的区域中间有空行,就不好用
Sub test84()
Range("a1").End(xlDown).End(xlToRight).Select
Debug.Print Range("a1").End(xlDown).End(xlToRight).Address
Debug.Print Range("a1").End(xlDown).End(xlToRight).Value
End Sub
总结
-
情形1:如果当前sheet里只有1个range
那么本文的4种方法都是可以的,这4种方法都可以
- range().specialcells(xlcelltypelasetcell)
- 或 usedrange().address
- 或 Range("a65536").End(xlUp).Row
- 或 Range("a1").End(xlDown).End(xlToRight)
-
情形2:但经常是1个sheet里有多个不连续区域有数据,这几种方法差别较大
- Range("a65536").End(xlUp).Row
- cells(rows.count,1).End(xlUp).Row
- 这用法可以识别带空行的区域,如果目标是找这种range() ,比如查一列的最后一个有值的单元格,用这个更好
- Range("a1").End(xlDown).End(xlToRight)
- 这个只会查一个区域,不会查到其他区域,但是中间有空行的区域是不适合这么查的
- range().specialcells(xlcelltypelasetcell)
- usedrange().address
- 这两种更适合,目标是查找全表所有用过的区域的 这种情况