wdmexcel / 待分类 / #Excel VBA#解读(36):快速移动单元格—...

分享

   

#Excel VBA#解读(36):快速移动单元格——End属性

2015-10-27  wdmexcel

《完美Excel》微信公众账号:excelperfect

我是一个急性子,干什么事都希望马上能够完成,也希望马上能够知道事情的结果,去什么地方也希望马上能够到达目的地。我不知道大家是不是都跟我一样,但我知道Excel中有满足我们这些急性子人的快速功能。

下图所示为带有一组数据的工作表,活动单元格(也称为当前单元格)为单元格A1。按下<Ctrl+向下箭头键>组合键,当前单元格会快速移动到单元格A10;接着按下<Ctrl+向右箭头键>组合键,当前单元格会快速移动到单元格C10;再按下<Ctrl+向上箭头键>组合箭,当前单元格会快速移动到单元格C1;再按下<Ctrl+向左箭头键>组合箭,当前单元格又回到单元格A1

现在,在Excel中打开宏录制器(即单击开发工具”——“录制宏),从当前单元格A1开始,按上面所述的方法,使用 Ctrl+方向箭组合箭快速移动单元格,即从A1移至A10再移至C10再移至C1最后回到A1,最后关闭宏录制器(即单击开发工具”——“停止录制)。

宏录制器录制的代码如下:

Sub 1()

'

' 1

'

'

Selection.End(xlDown).Select

Selection.End(xlToRight).Select

Selection.End(xlUp).Select

Selection.End(xlToLeft).Select

End Sub

将录制的宏代码与对应的操作解析如下所示:


观察宏录制的代码和相应的解析,可以看出Selection代表当前活动单元格,单元格对象的End属性使单元格快速移动到同一列或行的末尾或者开头,其括号内的参数值指示单元格移动的方向。

End属性的语法表达式为:

Range对象.End(Direction)

返回一个Range对象,代表连续区域内的一个单元格,该单元格在该区域的末尾或开头。

说明:

  • Range对象代表区域内的任一单元格。也就是说,不一定是上文所演示的第一个单元格,可以是其它任何单元格。

  • 参数Direction的取值及说明如下:


以本文开头所示的工作表为例,说明End属性的使用。

下面的语句:

Range('B5').End(xlUp).Select

选择单元格B1

下面的语句:

Range('B5').End(xlDown).Select

选择单元格B10

下面的语句:

Range('B5').End(xlToLeft).Select

选择单元格A5

下面的语句:

Range('B5').End(xlToRight).Select

选择单元格C5

注意:上面的示例均为在同一行或列中连续的单元格区域中移动,也就是说区域中没有空单元格。如果列或行中存在空单元格,那么在向下或向右移动时,End属性将单元格移动到同一列或行中空单元格之前的那个单元格;在向上或向左移动时,End属性将单元格移动到同一列或行中空单元格之后的那个单元格。(我们可以在工作表中输入一些数据,并有意在数据之间留有空单元格,然后使用Ctrl+箭头方向键试验,体会Excel是怎么快速移动单元格的)

一般,我们使用End属性查找连续单元格区域的最后一个单元格所在的行或列。

仍然以本文开头所示的工作表为例,下面的语句:

Range('A1').End(xlDown).Select

选择单元格A10。即列A中有数据的单元格区域的最后一个单元格。

继续!下面的语句:

Range('A10').End(xlDown).Select

选择单元格A1048576(如果是Excel 2003则为A65536),即列A中的最后一个单元格。换句话说,以有数据的单元格区域的最后一个单元格为起点,结合参数值xlDown(向下移)使用End属性,活动单元格将移动到工作表中该列或该行所在的最后一个单元格。呵呵,有点意思了!

再试试下面的语句(Excel 2007及以上版本):

Range('A1048576').End(xlUp).Select

或者是(Excel 2003及以下版本):

Range('A65536').End(xlUp).Select

选择单元格A10。也就是列A中有数据的单元格区域的最后一个单元格。

我们来小结一下。

类似于本文开头所示的工作表,如果列A中的单元格区域放置着连续的数据,即表中的单元格区域A1:A10,我们要找到列A中存放数据的最后一个单元格,有两种方法。第一种是从单元格A1开始使用End属性向下移至A10,即语句Range('A1').End(xlDown).Select。第二种是从工作表列A中的最后一个单元格开始向上移至A10,即语句Range('A1048576').End(xlUp).Select

但是,如果在A1:A10中某个单元格为空(假设是单元格A5),那么语句Range('A1').End(xlDown).Select就不会移至单元格A10,而是移至单元格A4。所以,第一种方法不保险,仅在能确保单元格区域连续的情况下使用。通常,我们偏向于使用第二种方法,即从工作表中列中的最后一个单元格向上移,确保能移至该列中最后一个有数据的单元格上。

看看使用第二种方法选取单元格区域最后一个单元格的语句,对于Excel 2007之前或之后的版本,由于行数不同,使用的单元格也不一样:Range('A1048576')Range('A65536')

在本系列前面的文章中曾介绍,Application对象有一个Rows属性,可以返回工作表所在的行。该属性也可以返回工作表中的总行数,语句如下:

Rows.Count

如果是Excel 2003,则返回值65536;如果是Excel 2007及以后的版本,则返回值1048576

因此,工作表列A中处于最底端(即最后)一个单元格可表示为:

Range('A' & Rows.Count)

从而上述第二种方法的代码也可以写为:

Range('A' &Rows.Count).End(xlUp).Select

同样是选择单元格A10(即列A中有数据的单元格区域的最后一个单元格)。并且,该代码更具有通用性,这样就不怕Excel的版本问题了。

注意:上面是以列为例来说明如何选取某列中的最后一个有数据的单元格,对于行来说,如何选取某一行中最后一个有数据的单元格,与上面的方法相同,只是需要修改相关参数。

下面,继《Excel VBA解读(32):到达想要的单元格——Offset属性》后,我们使用End属性继续对《Excel VBA解读(19):员工管理系统开发V1.0》中的系统进行优化,使代码更加灵活。代码如下:

Sub TotalData2()

'声明Worksheet变量

Dim wksInfo As Worksheet

Dim wksBaseInfo As Worksheet

'声明单元格对象变量

Dim rng As Range

'声明变量以记录最后一行之后的空行行号

Dim lRow As Long

'wksInfo变量赋值

Set wksInfo =ThisWorkbook.Worksheets('员工信息数据库')

Set wksBaseInfo =ThisWorkbook.Worksheets('员工基本信息表')

'找到列A中存在数据的最后一个单元格之后的单元格所在行号

lRow = wksInfo.Range('A' &Rows.Count).End(xlUp).Row + 1

'将初始单元格赋值给变量

Set rng = wksInfo.Range('A' &lRow)

'<员工基本信息表>中数据自动填入<员工信息数据库>工作表

With wksBaseInfo

rng.Value = Range('B2').Value

rng.Offset(0, 1).Value = .Range('F2').Value

rng.Offset(0, 2).Value =.Range('B3').Value

rng.Offset(0, 3).Value =.Range('D3').Value

rng.Offset(0, 4).Value =.Range('F3').Value

rng.Offset(0, 5).Value =.Range('B4').Value

rng.Offset(0, 6).Value =.Range('D4').Value

rng.Offset(0, 7).Value =.Range('F4').Value

rng.Offset(0, 8).Value =.Range('B5').Value

rng.Offset(0, 9).Value =.Range('F5').Value

rng.Offset(0, 10).Value =.Range('B6').Value

rng.Offset(0, 11).Value =.Range('D6').Value

rng.Offset(0, 12).Value =.Range('F6').Value

rng.Offset(0, 13).Value =.Range('B7').Value

rng.Offset(0, 14).Value =.Range('F7').Value

rng.Offset(0, 15).Value =.Range('B8').Value

rng.Offset(0, 16).Value =.Range('D8').Value

rng.Offset(0, 17).Value =.Range('F8').Value

rng.Offset(0, 18).Value =.Range('B9').Value

rng.Offset(0, 19).Value =.Range('D9').Value

rng.Offset(0, 20).Value =.Range('F9').Value

rng.Offset(0, 21).Value =.Range('B10').Value

rng.Offset(0, 22).Value =.Range('B11').Value

rng.Offset(0, 23).Value =.Range('B12').Value

End With

End Sub

经过改进后的代码可以连续地将<员工基本信息表>工作表中填写的记录自动填充到<员工信息数据库>工作表中的相应位置,并且能够自动扩展,而不会覆盖已经存在的记录信息。

当您对VBAExcel的对象模型越来越熟悉后,可以使用不同的代码来实现同样的功能。下面的代码只需修改原来的代码(即TotalData1过程)中给初始单元格赋值的语句,实现相同的功能:

Sub TotalData3()

'声明Worksheet变量

Dim wksInfo As Worksheet

Dim wksBaseInfo As Worksheet

'声明单元格对象变量

Dim rng As Range

'wksInfo变量赋值

Set wksInfo =ThisWorkbook.Worksheets('员工信息数据库')

Set wksBaseInfo =ThisWorkbook.Worksheets('员工基本信息表')

'将初始单元格赋值给变量,即列A中最后一个数据单元格之后的单元格

Set rng = wksInfo.Range('A' &Rows.Count).End(xlUp).Offset(1, 0)

'<员工基本信息表>中数据自动填入<员工信息数据库>工作表

With wksBaseInfo

rng.Value = Range('B2').Value

rng.Offset(0, 1).Value =.Range('F2').Value

rng.Offset(0, 2).Value =.Range('B3').Value

rng.Offset(0, 3).Value =.Range('D3').Value

rng.Offset(0, 4).Value =.Range('F3').Value

rng.Offset(0, 5).Value =.Range('B4').Value

rng.Offset(0, 6).Value =.Range('D4').Value

rng.Offset(0, 7).Value =.Range('F4').Value

rng.Offset(0, 8).Value =.Range('B5').Value

rng.Offset(0, 9).Value =.Range('F5').Value

rng.Offset(0, 10).Value =.Range('B6').Value

rng.Offset(0, 11).Value =.Range('D6').Value

rng.Offset(0, 12).Value =.Range('F6').Value

rng.Offset(0, 13).Value =.Range('B7').Value

rng.Offset(0, 14).Value =.Range('F7').Value

rng.Offset(0, 15).Value =.Range('B8').Value

rng.Offset(0, 16).Value =.Range('D8').Value

rng.Offset(0, 17).Value =.Range('F8').Value

rng.Offset(0, 18).Value = .Range('B9').Value

rng.Offset(0, 19).Value =.Range('D9').Value

rng.Offset(0, 20).Value =.Range('F9').Value

rng.Offset(0, 21).Value =.Range('B10').Value

rng.Offset(0, 22).Value =.Range('B11').Value

rng.Offset(0, 23).Value =.Range('B12').Value

End With

End Sub

--------------------------------------

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多

    ×
    ×

    ¥.00

    微信或支付宝扫码支付:

    开通即同意《个图VIP服务协议》

    全部>>