60

好的,我正在完成一个旧版 Excel-VBA 应用程序的附加项目,我再次遇到了神秘range.Rows(?) 和worksheet.Rows属性的难题。

有谁知道这些属性的真正作用以及它们应该为我提供什么?(注意:所有这些可能也适用于相应的*.Columns属性)。

我真正希望能够使用它的是返回一系列行,如下所示:

   SET rng = wks.Rows(iStartRow, iEndRow)

但是我从来没有能够让它做到这一点,即使 Intellisense 显示了两个论据。相反,我必须使用其他两种或三种(非常笨拙的)技术中的一种。

该帮助非常无用(对于 Office VBA 通常如此),并且无论我添加多少其他术语,谷歌搜索“行”都不是很有用。

我能够使用它的唯一事情是 1) 返回单行作为范围 ( rng.Rows(i)) 和 2) 返回范围 ( ) 中的行数rng.Rows.Count。是这样吗?真的没有其他好处了吗?

澄清:我知道它返回一个范围,并且还有其他方法可以获取一系列行。我所要求的具体是我们从中得到什么.Rows(),我们还没有从.Cells()and得到.Range()什么?我知道的两件事是 1)返回单行范围的更简单方法和 2)计算范围内行数的方法。

还有别的事吗?

4

9 回答 9

53

Range.RowsRange.Columns返回基本相同的 Range,除了新 Range 有一个标志表示它表示 Rows 或 Columns 的事实。这对于某些 Excel 属性(例如 Range.Count 和 Range.Hidden)以及某些方法(例如Range.AutoFit()

  • Range.Rows.Count返回 Range 中的行数。
  • Range.Columns.Count返回 Range 中的列数。
  • Range.Rows.AutoFit()自动调整 Range 中的行。
  • Range.Columns.AutoFit()自动调整 Range 中的列。

您可能会发现它Range.EntireRow并且Range.EntireColumn很有用,尽管它们仍然不是您想要的。它们为表示的范围返回所有可能的列EntireRow和所有可能的行。EntireColumn

我知道这一点是因为用于 .NET 的 SpreadsheetGear带有与 Excel 的 API 非常相似的 .NET API。SpreadsheetGear API 为 IRange 索引器提供了几个强类型重载,包括您可能希望 Excel 具有的重载:

  • IRange this[int row1, int column1, int row2, int column2];

免责声明:我拥有 SpreadsheetGear LLC

于 2009-06-24T16:20:54.220 回答
11

Range.Rows、Range.Columns 和 Range.Cells 是 Excel.Range 对象,根据 VBA Type() 函数:

?TypeName(Selection.rows)
范围
然而,这还不是全部:这些返回的对象是继承 Excel::Range 的每个属性和方法的扩展类型 - 但是 .Columns 和 .Rows 有一个特殊的 For... 每个迭代器和一个特殊的 .Count 属性'与父 Range 对象的迭代器和计数不太一样。

所以 .Cells 被迭代并算作单个单元格范围的集合,就像父范围的默认迭代器一样。

但是 .Columns 被迭代并计为垂直子范围的集合,每个子范围都是单列宽;

...并且 .Rows 被迭代并计为水平子范围的集合,每个子范围都是单行高。

理解这一点的最简单方法是单步执行此代码并查看选择的内容:

公共子测试()
将子范围调暗为范围 将ParentRange 作为范围
设置 ParentRange = ActiveSheet.Range("B2:E5")

对于 ParentRange.Cells 中的每个子范围 子范围.选择 下一个
对于 ParentRange.Rows 中的每个子范围 子范围.选择 下一个
对于 ParentRange.Columns 中的每个子范围 子范围.选择 下一个
对于 ParentRange 中的每个子范围 子范围.选择 下一个
结束子
享受。并尝试在那里合并几个单元格,看看合并范围有多奇怪。

于 2014-04-30T17:58:15.997 回答
7

你的两个例子是我唯一使用过RowsColumns属性的东西,但理论上你可以用它们做任何可以用Range对象做的事情。

这些属性的返回类型本身就是 a Range,因此您可以执行以下操作:

Dim myRange as Range
Set myRange = Sheet1.Range(Cells(2,2),Cells(8,8))
myRange.Rows(3).Select

myRange这将选择(Sheet1 中的单元格 B4:H4)中的第三行。

更新:要做你想做的事,你可以使用:

Dim interestingRows as Range
Set interestingRows = Sheet1.Range(startRow & ":" & endRow)

更新#2:或者,从另一个范围内获取行的子集:

Dim someRange As Range
Dim interestingRows As Range

Set myRange = Sheet1.Range(Cells(2, 2), Cells(8, 8))

startRow = 3
endRow = 6

Set interestingRows = Range(myRange.Rows(startRow), myRange.Rows(endRow))
于 2009-06-24T14:06:21.763 回答
5

由于 .Rows 结果被标记为由行组成,因此您可以“For Each”它单独处理每一行,如下所示:

Function Attendance(rng As Range) As Long
Attendance = 0
For Each rRow In rng.Rows
    If WorksheetFunction.Sum(rRow) > 0 Then
        Attendance = Attendance + 1
    End If
Next
End Function

我用它来检查人员列表(不同行)的几个类别(不同列)中的任何一个的出勤率。

(当然,您可以使用 .Columns 在范围内的列上执行“For Each”。)

于 2014-03-06T21:45:33.400 回答
2

我不确定,但我认为第二个参数是红鲱鱼。

.Rows 和 .Columns 都采用两个可选参数:RowIndex 和 ColumnIndex。尝试使用 ColumnIndex,例如.Rows 和 .Columns 都会Rows(ColumnIndex:=2)产生错误。

我觉得它在某种意义上是从Cells(RowIndex,ColumnIndex)Property 继承的,但只有第一个参数是合适的。

于 2009-06-24T14:26:59.083 回答
2

我发现自己在 Copy 方法中使用 range.Rows 来获得它的效果。它将行的高度从原点复制到目的地,这是我想要的行为。

rngLastRecord.Rows.Copy Destination:=Sheets("Availability").Range("a" & insertRow)

如果我使用 rngLastRecord.Copy 而不是 rngLastRecord.Rows.Copy,那么行高将是复制之前的任何值。

于 2011-06-29T12:24:13.137 回答
1

我发现这很有效:

Rows(CStr(iVar1) & ":" & CStr(iVar2)).Select
于 2012-09-16T15:58:05.430 回答
1

还有一种方法,以这个为例

Dim sr As String    
sr = "6:10"
Rows(sr).Select

iStartRow您需要做的就是将变量转换iEndRow为字符串。

于 2010-12-23T21:41:11.087 回答
1

这可能有点杂乱无章,但以下代码可以完成您似乎想要做的事情:

Set rng = wks.Range(wks.Rows(iStartRow), wks.Rows(iEndRow)).Rows
于 2010-03-12T02:50:16.463 回答