Excel中range和cells的详解

1. 单元格Bi 可以使用以下3中表示方法
Range("B" & i )
Cells( i , 2 ) 
Cells( i , "B") (当列号较大、不易计算时,如“H"、”AD",我们可以直接用双引号加列标作为第二参数)
使用Range、Cells是比较常用的写法,方便,易记,规律性较好!对单元格访问,速度最快的的是 Cells(1,1) ,其次是 Range("A1"), 最慢是 [A1],    Cells() 快于 Range()  快于 [],因此多循环中建议使用 Cells()。Range("B" & i )
Cells( i , 2 ) 
Cells( i , "B") (当列号较大、不易计算时,如“H"、”AD",我们可以直接用双引号加列标作为第二参数)
使用Range、Cells是比较常用的写法,方便,易记,规律性较好!对单元格访问,速度最快的的是 Cells(1,1) ,其次是 Range("A1"), 最慢是 [A1],    Cells() 快于 Range()  快于 [],因此多循环中建议使用 Cells()。

2. Range、Cells都可以表达单元格/区域
Range 中文意思是“区域”,Cells 中文意思是“单元(格)”,所以,用Cells()可以表达一个单元格区域吗?
比如说,我们想表示A2:D3这个区域,用Cells()可以实现吗?那么,用Range()呢?
因此,单独用Cells()只能表示某个单元格,而不能表示一个区域。
显然,Range是可以兼容Cells的表达方式,但Range更倾向于区域有“固定”因素时使用,当代码里要使用行、列参数都是变量的单元格时,  直接用Range来表达的话,就显得有心有力了……   而Cells()在这时候,就是最好的选择。所以我们要适时选择其一,或者用Range(Cells(),Cells())的联合方式,总之让自己方便,让代码高效……

3. 各个代码所表示的单元格
① Range("C4")(2,3)  = E5
② Range("C5")(-2,1)    =C2
③ Cells(2,3)(2.5)       = C3
④  Cells(2,3)(3.5)        =C5
⑤ Range("A1:A5").Item(2)  =A2
⑥ Range("B2:B5").Range("A2")  = B3
如果不知道规则,那可以用VBA代码测试,比如说我们可以用Range("C4")(2,3).Select 根据运行后选择的单元格来判断结果,    也可以用Debug.Print Range("C4").Item(2, 3).Address(0, 0)来获得地址,Address后面的参数省略的话可以得到绝对地址,是一样的。

4. 为什么会有像Range("C4")(2,3)这种表达方式呢,表示的又是什么意思呢?
上面的代码,其实就是Range("C4").Item(2, 3)简化掉中间的“Item”得到的,指的就是以C4单元格为中心,按一定偏移量所得到的单元格。帮助文件的说法:表达式.Item(RowIndex, ColumnIndex)  而表达式 就是指一个代表 Range 对象的变量。如果 RowIndex 指定为 1,则返回区域内第一行中的单元格,而非工作表的第一行。例如,如果选定区域为单元格 C3,则 Selection.Cells(2, 2) 返回单元格 D4(使用 Item 属性可在原始区域之外进行索引)。即:表达式前面指定的单元格,将作为偏移原点,而原点的坐标是(1,1),跟我们日常接触的(0,0)有所差别,具体坐标如下图所示,因为坐标原点不是0,所以计算时比较容易搞混,因此这种方法较少用,通常都会使用OFFSET(),因为OFFSET()的偏移量是按增量,容易计算。

5. 为什么Cells(2,3)(2.5) 跟 Cells(2,3)(3.5) 一个是C3、一个是C5相差2个单元格之多?
首先,2.5与3.5,会由内部先取整,然后再如上面的偏移方式进行计算,但VBA内部,默认的取整方式,跟我们通常意义的四舍五入有点差别,跟VB一样,这里是遵循“四舍六入、五取偶”的方式,也称为“四舍六入,逢五奇进偶舍”,即当进位的下一位为5时,则统一向偶数靠拢。比如说2.5,取整则为2(舍),3.5取整为4(进),所以上面的两个Cells会相差两个单元格,VBA里的Round()函数也是遵循这一规则,跟Excel函数Round()也是有区别的。

6.Range.Range、Range.Cells等的理解。
上面的第一个Range指的是一块区域,我们可以称为“母对象”,第二个Range指的是一块区域里的第几个单元格,可以理解为“子对象”;我们日常用的Range、Cells其实也有一个母对象,那就是“全部单元格”,如果这个理解了,那上面的也就比较容易掌握。 如Range("B2:B5").Range("A2"),就是指B2:B5单元格区域里第1列,第2行的那个单元格,即(B3);这种单元格表达方式比较不常用,因为计算方法也比较复杂,所以较少用得上,即使是区域循环,也会用For Each in ... Next 来解决,因此,大家理解及了解有这种表达方式即可。

7. 什么时候可以省略.Value,什么时候不可以呢?
很多人都说,其实.Value是Range的默认属性,所以可以省略,但当我们有时候省略时,又会出错,这是怎么一回事呢?
可以这么说,即使Range的默认属性是.Value,当我们没有明确指定时,编译时就需要进行“自动类型适应”的过程,如果过程进行不下去,就会有错误发生,如:  i = Range("A1")    或   Range("A1") = 256,因为有一种“默认”及“适应”性,所以不会把A1的 Address属性 ($A$1) 赋给 i ,也不会把256 赋给A1的Height属性,而是赋给了.Value。
下面说说无法适应的问题,比如说,我们A1单元格存储了另外一个工作表的名称,假设为“工作表2”,也就是说Range("A1") = "工作表2",
我们现在想删除A1单元格所指定的工作表,用 Sheets(Range("A1")).Delete 会怎么样呢?答案是:会报错——“运行错误'13',类型不匹配”。但稍作修改,比如说将A1单元格的内容修改为2,那么仍然是用Sheets(Range("A1")).Delete这代码,运行后会怎么样呢?答案是:不会出错。
那么,A1仍然是“工作表2”,而是将代码改为Sheets(CStr(Range("A1"))).Delete,结果又怎么样呢?答案是:正常运行!
这说明什么问题呢?首先,Sheets()指的是某个对象,括号里可以用数字、也可以用文本作为参数来表示某个工作表,从上面不难看出来,其默认处理方式是数值格式,也就是表示工作表的序号,当我们使用“工作表2”这个文本想进入其默认处理方式时,就会存在无法匹配的问题,因此报错,而当我们用Cstr()函数,将A1的值,强制转换为文本类型然后再提供给Sheets(),这时候就是让其接受文本值,也理所当然会按工作表名来接收,所以顺利进行。

猜你喜欢

转载自blog.csdn.net/yaroo/article/details/78773414
今日推荐