好的,我正在为遗留的Excel-VBA应用程序完成一个附加项目,我再一次遇到了神秘的range.Rows
(?)和worksheet.Rows
属性的难题。
有谁知道这些属性真正做了什么以及它们应该为我提供什么? (注意:所有这些也可能适用于相应的*.Columns
属性)。
我真正喜欢能够使用它是为了返回一系列行,如下所示:
SET rng = wks.Rows(iStartRow, iEndRow)
但是我从来没有能够做到这一点,即使Intellisense为它显示了两个参数。相反,我必须使用其他两种(非常kludgy)技术中的一种。
帮助是非常无益的(对于Office VBA通常如此),并且对于“Rows”进行Google搜索并不是很有用,无论我添加了多少其他术语。
我能够使用它的唯一事情是1)返回单行作为范围(rng.Rows(i)
)和2)返回范围内的行数(rng.Rows.Count
)。是吗?真的没有别的东西吗?
澄清:我知道它会返回一个范围,并且还有其他方法可以获取一系列行。我要求的是具体来自.Rows()
我们尚未从.Cells()
和.Range()
得到什么?我知道的两件事是1)返回单行范围的简单方法和2)计算范围内行数的方法。
还有别的吗?
答案 0 :(得分:52)
Range.Rows
和Range.Columns
基本上返回相同的Range,除了新Range有一个标志表示它代表行或列的事实。对于某些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
所有可能的行。
我知道这是因为SpreadsheetGear for .NET附带的.NET API与Excel的API非常相似。 SpreadsheetGear API为IRange索引器提供了几个强类型重载,包括您可能希望Excel具有的重载:
IRange this[int row1, int column1, int row2, int column2];
免责声明:我拥有SpreadsheetGear LLC
答案 1 :(得分:9)
根据VBA Type()函数,Range.Rows,Range.Columns和Range.Cells是Excel.Range对象:
?TypeName(Selection.rows) Range但是,这不是全部故事:那些返回的对象是从Excel :: Range继承每个属性和方法的扩展类型 - 但.Columns和.Rows有一个特殊的For ...每个迭代器,以及一个特殊的.Count属性't 完全与父Range对象的迭代器和计数相同。
因此.Cells被迭代并计为单单元格范围的集合,就像父范围的默认迭代器一样。
但是.Columns被迭代并计为一组垂直子范围,每个子范围都是一列;
...而且.Rows被迭代并计为一组水平子范围,每个水平子范围都是一行高。
理解这一点的最简单方法是逐步执行此代码并观察所选内容:
Public Sub Test()请享用。并尝试使用其中的几个合并单元格,只是为了看看奇数合并范围是多少。
Dim SubRange As Range Dim ParentRange As Range
Set ParentRange = ActiveSheet.Range("B2:E5")
For Each SubRange In ParentRange.Cells SubRange.Select Next
For Each SubRange In ParentRange.Rows SubRange.Select Next
For Each SubRange In ParentRange.Columns SubRange.Select Next
For Each SubRange In ParentRange SubRange.Select Next
End Sub
答案 2 :(得分:7)
您的两个示例是我使用Rows
和Columns
属性的唯一内容,但理论上您可以使用Range
对象执行任何操作
这些属性的返回类型本身是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))
答案 3 :(得分:3)
由于.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”。)
答案 4 :(得分:2)
我不确定,但我认为第二个参数是红鲱鱼。
.Rows和.Columns都有两个可选参数:RowIndex和ColumnIndex。尝试使用ColumnIndex,例如Rows(ColumnIndex:=2)
,为 .Rows和.Columns 生成错误。
我觉得它在某种意义上是从Cells(RowIndex,ColumnIndex)
属性继承的,但只有第一个参数是合适的。
答案 5 :(得分:2)
我发现自己在Copy方法中使用了range.Rows的效果。它将行的高度从原点复制到目标,这是我想要的行为。
rngLastRecord.Rows.Copy Destination:=Sheets("Availability").Range("a" & insertRow)
如果我使用rngLastRecord.Copy而不是rngLastRecord.Rows.Copy,则行高将是复制之前的任何内容。
答案 6 :(得分:1)
它可能有点像kludge,但以下代码可以做你想做的事情:
Set rng = wks.Range(wks.Rows(iStartRow), wks.Rows(iEndRow)).Rows
答案 7 :(得分:1)
我发现这有效:
Rows(CStr(iVar1) & ":" & CStr(iVar2)).Select
答案 8 :(得分:0)
还有另一种方式,以此为例
Dim sr As String
sr = "6:10"
Rows(sr).Select
您需要做的就是将变量iStartRow
,iEndRow
转换为字符串。