Excel范围按行或列排列

Excel Range类似乎有一个未公开的属性,它决定了ItemCellsCount属性如何工作(以及其他类的方法和属性,很可能)。

普通Range似乎有“细胞”的configuration; 即访问它们的属性需要一个Cell索引。

 Set x = [A1:H50] ?TypeName(x) Range ?x.Address $A$1:$H$50 ?x.Count 400 ?x(20).Address $D$3 

但是,您也可以获得“列”或“行”分配Range ,其行为有所不同。

 Set x = [A1:H50].Columns ?TypeName(x) Range ?x.Address $A$1:$H$50 ?x.Count 8 ?x(20).Address $T$1:$T$50 

我正在尝试为Range编写一个包装类,其performance会比多Area范围的内置types更好。 我想更好地了解这个范围“性格”是如何工作的。 是否有一个内置的属性或其他简单的方法来testing一个Range对象具有的“处置”? “处置”是范围的不可变属性,还是有一种方法可以在不使用“行”,“列”或“单元格”属性获取新范围的情况下进行更改?

我不知道这种行为甚至存在。 我查看了Range对象的属性列表,但是我找不到任何解决这个需求的东西。 相反,我写了一个function,我想告诉你“性格”,我称之为定向。

 Function getOrientation(ByVal Rng As Range) As String 'If only one row, it's a column orientation If Rng.Rows.Count = 1 Then getOrientation = "Column" Exit Function End If 'If only one column, it's a row orientation If Rng.Columns.Count = 1 Then getOrientation = "Row" Exit Function End If 'If the cell count matches the expected cell count, it's Both If Rng.Count = Rng.Columns.Count * Rng.Rows.Count Then getOrientation = "Both" ElseIf Rng.Count = Rng.Columns.Count Then getOrientation = "Column" Else getOrientation = "Row" End If End Function Sub Test() 'Testing Debug.Print getOrientation(Range("A1:B100").Columns) Debug.Print getOrientation(Range("A1:B100").Rows) Debug.Print getOrientation(Range("A1:B100")) Debug.Print getOrientation(Range("A1:A100")) Debug.Print getOrientation(Range("A1:C1")) End Sub 

其实MSDN文档说

返回表示指定范围中的列的Range对象

这意味着它返回一个列的Collection ,以便.Count将返回集合元素的数量,即列的数量

但是它也增加了:

当应用于多区域select的Range对象时,此属性仅返回范围的第一个区域的列。 例如,如果Range对象有两个区域 – A1:B2和C3:D4 – Selection.Columns.Count返回2,而不是4。

而立即给出的方式:

要在可能包含多区域select的范围上使用此属性,请testingAreas.Count以确定范围是否包含多个区域。 如果是这样,则循环遍历范围中的每个区域

因此需要一些包装来增强Range对象的默认成员

这将是extension methods的完美空间,这在VBA中是不可能的

所以下一步应该是定义一个类

例如,你可以用下面的代码添加一个以“MyRange”命名的新类:

 Option Explicit Dim rng As Range Public Property Set Range(r As Range) Set rng = r End Property Public Property Get Range() As Range Set Range = rng End Property Function ColumnsCount() As Long '<-- your personalized "Columns.Count" function correctly calculates the number of columns of your range Dim area As Range If rng Is Nothing Then Exit Function For Each area In rng.Areas ColumnsCount= ColumnsCount+ area.Columns.Count Next area End Function 

你的代码会利用这个“MyRange”类如下

 Option Explicit Sub main() Dim rng As Range ' "normal" range type Dim myRng As MyRange ' your "personalized" range type Set rng = Range("A1:B2, C3:D5") '<-- set a "normal range" object Set myRng = New MyRange '<--| set your "personalized range" object Set myRng.Range = rng '<-- give it the "normal" range as its "rng" property MsgBox rng.Columns.Count '<-- this will return 2 MsgBox myRng.ColumnsCount '<-- this will return 4 End Sub