首页 > 解决方案 > Range() vs Cells() vs Range.Cells()

问题描述

我知道Range()andCells()属性是访问工作表上单元格的等效方法。但是,什么时候Range.Cells()在这种组合中使用是明智的?

我遇到了一个他们使用的例子Range("A1").Resize(2,3).cells.value。这相当于Range("A1").Resize(2,3).value

如果不是,前者的优势是什么?

标签: vbaexcel

解决方案


从技术上讲,Range并不Range.Cells等同。有一个很小但很重要的区别。

但是,在您的特定情况下,您在哪里

  1. Range("something")用和构造范围
  2. 只对.Value那个范围的那个感兴趣,

它根本没有区别


VB 中有一个方便的子句For Each,它枚举集合中的所有元素。在 Excel 对象模型中,有一些方便的属性,例如ColumnsRowsCells,它们返回各个单元格跨度的集合:列集合、行集合或单元格集合。

从语言的流动方式来看,您自然会期望它For Each c In SomeRange.Columns会枚举列,一次一个,然后For Each r In SomeRange.Rows枚举行,一次一个。事实上,他们就是这样做的。
但是您可以注意到该Columns属性返回 a Range,并且该Rows属性也返回 a Range。然而,前者Range会告诉For Each它它是“列的集合”,而后者Range会将自己介绍为“行的集合”。

这是有效的,因为显然在类的每个实例中都有一个隐藏标志Range,它决定了这个实例RangeFor Each.

查询CellsaRange可确保您获得一个RangeFor Each枚举模式设置为“单元格”的实例。如果您不打算从For Each一开始就进入范围,那么这种差异对您没有任何影响。

即使您确实关心For Each模式,在您的特定情况下Range("A1").Resize(2,3)也是Range("A1").Resize(2,3).Cells相同的,因为默认情况下,它Range是使用“单元格”的枚举模式构造的,并且Resize不会更改它调整大小的范围的枚举模式。


因此,我能想到的唯一情况是Cells从已经存在的查询中产生影响Range,即当您有一个接受 aRange作为参数的函数时,您不知道它Range是如何构造的,您想枚举单个单元格该范围,并且您要确保它的单元格For Each将被枚举,而不是行或列:

function DoSomething(byval r as range)
  dim c as range

  'for each c in r ' Wrong - we don't know what we are going to enumerate

  for each c in r.cells ' Make sure we enumerate cells and not rows or columns (or cells sometimes)
    ...
  next
end function

推荐阅读