【问题标题】:What does the Excel range.Rows property really do?Excel range.Rows 属性的真正作用是什么?
【发布时间】:2010-11-05 12:42:11
【问题描述】:

好的,我正在完成一个旧版 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().Range() 得到什么?我知道的两件事是 1)返回单行范围的更简单方法和 2)计算范围中行数的方法。

还有别的吗?

【问题讨论】:

  • RBY - 我想差不多就是这样。这是操作整行工作表/范围的一部分(非常有用!)的便捷方式,并带有 Count 启动。当您运行多行(或多列)时,循环最有用。
  • 好问题...除了 .Count 我想知道它们是干什么用的。
  • 我想知道为什么这个问题似乎引发了每个人发布“答案”的冲动,这些“答案”仅仅是猜测,甚至没有解决这个问题! -1 给每个人!! (最后一部分是个玩笑。主要是。)
  • 是的,很奇怪。更奇怪的是,尽管我有超过 6000 分,几乎都是从回答 SQL Server 问题中获得的,但我唯一的金牌徽章来自这个问题的近 25,000 次浏览,这真的只是我的闲暇好奇心。然而,对它的兴趣是我在这里所做的任何其他事情的 10 倍。不完全是一个自我建设者。
  • +1 个有趣的问题。

标签: vba excel ole-automation


【解决方案1】:

Range.RowsRange.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.EntireRowRange.EntireColumn 很有用,尽管它们仍然不是您想要的。它们返回 EntireRow 的所有可能列和 EntireColumn 表示范围的所有可能行。

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

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

免责声明:我拥有 SpreadsheetGear LLC

【讨论】:

  • essentially the same Range... 错过了这些属性的一个有价值的部分,即它们为For Each 循环提供了一个新的迭代器,该循环通过Range 逐行或逐列进行。请参阅answer by Nile 以供参考。这在与SpecialCells 或其他不连续范围(例如来自AutoFilter)结合使用时非常强大。具体示例:当您没有 Table 时,在 AutoFilter 之后快速将带状行着色应用于可见数据。
  • @ByronWall 感谢您的评论,因为我发现自己在此页面上寻找有关将 range.rows 属性用于此确切目的的具体信息。非常感谢您对这个用例的指点。
【解决方案2】:

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

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

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

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

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

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

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

对于 ParentRange.Cells 中的每个子范围 子范围.选择 下一个
对于 ParentRange.Rows 中的每个子范围 子范围.选择 下一个
对于 ParentRange.Columns 中的每个子范围 子范围.选择 下一个
对于 ParentRange 中的每个子范围 子范围.选择 下一个
结束子 享受。并在其中尝试几个合并的单元格,看看 odd 合并范围如何。

【讨论】:

  • THIS 是所有“RowsColumns 除了Count”之外的答案中缺少的部分。在不考虑 Range 的创建方式的情况下迭代范围的行和列的能力非常强大。它提供了一种非常简洁的方式来迭代单元格,从而避免循环内的Cells(i,j) 类型逻辑。它也适用于在某些情况下可能出现的不连续范围。
【解决方案3】:

您的两个示例是我唯一使用过RowsColumns 属性的东西,但理论上你可以用它们做任何可以用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))

【讨论】:

  • 我知道它返回了一个范围(在我的原始帖子中提到过),并且还有其他方法可以获得一系列行(也提到过)。我要问的是我们从 .Rows() 中得到了什么,而我们还没有从 .Cells() 和 .Range() 中得到什么?我将在我的问题中澄清这一点......
  • 恐怕就是这样。 Rows 和 Columns 属性只是一个快速访问 Range 对象的快捷方式,可以方便地设置为包含初始范围的单行(或单列)。没有比这更神奇的了。
  • 我觉得自己像个白痴,没有想到 Set luckyRows = Sheet1.Range(startRow & ":" & endRow)。 (即使我想过,有些人会同意我的看法。)
  • '事实证明,interestingRows = Sheet1.Range(startRow & ":" & endRow) 根本不起作用。它没有崩溃,但是我最终达到的范围都不是我想要的。 testStr = 65 & ":" & 5 计算结果为“65:5”,但我不确定结果是什么范围。令人恼火的是,MS 认为不适合为这种事情。 AFAIK(尽管在 VBA 中并没有那么远)没有类似范围的构造函数接受行和列索引或单元格对。需求经常出现。
  • S 我将用于获取对较大范围的子范围的引用的旧的、乏味的方法放在函数 shown here 中。我的解决方案是构造一个“A4:G7”样式的字符串并将其提供给范围构造函数,如下所示: rangeStr = Chr(AM1 + iCol1) & CStr(iRow1) & ":" & Chr(AM1 + iCol2) & CStr(iRow2) ; _ 设置 getSubRange = sourceRange.Range(rangeStr)_。但肯定有更直接的方法直接使用索引,对吧?
【解决方案4】:

由于 .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”。)

【讨论】:

【解决方案5】:

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

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

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

【讨论】:

  • 感觉,无非是感觉 -1
  • @Jean-François Corbett - 有时这些是你能得到的唯一答案,拥有该领域的人的轶事总比什么都没有好。这些天我可能不会发布这样的东西(答案是 2 岁!!) - 它太毛茸茸了,我绝对不会费心发布一些投票希望渺茫的东西。 VBA 问题通常不会获得太多代表。但我强烈反对你的暗示,即“基于感觉的答案是错误的”只是因为这会结束对没有明显或简单答案的问题的辩论。
  • 我明白你的意思。老实说,我没有看日期,也没有意识到它这么旧。尽管如此,我觉得(原文如此)关于 SO 的这些猜测答案太多了,而且只有极少数有用,而大多数有资格被视为“无用”,即合法的否决候选人,我坚持我之前的判断这个。其他人显然对事情有不同的看法,因为您的回答/感觉仍然得到了净支持。
【解决方案6】:

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

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

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

【讨论】:

    【解决方案7】:

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

    Set rng = wks.Range(wks.Rows(iStartRow), wks.Rows(iEndRow)).Rows
    

    【讨论】:

    • 是的,我知道。不是我问的问题。
    • 虽然不是问这个问题,但来这里的人可能会问这个问题(就像我一样),所以我想我会提供它。
    • 也许更干净的使用with wks ... end with
    【解决方案8】:

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

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

    您只需将变量iStartRowiEndRow 转换为字符串。

    【讨论】:

      【解决方案9】:

      我发现这是可行的:

      Rows(CStr(iVar1) & ":" & CStr(iVar2)).Select
      

      【讨论】:

      • @RBarryYoung Rows(Cstr(iVar1) & ":" & CStr(iVar2)) 肯定与Cells(Cstr(iVar1) & ":" & CStr(iVar2)) 不同。后者会导致类型不匹配错误。
      猜你喜欢
      • 2011-08-19
      • 1970-01-01
      • 2017-10-19
      • 1970-01-01
      • 2013-02-23
      • 2012-09-19
      • 2014-04-26
      • 2015-10-14
      • 1970-01-01
      相关资源
      最近更新 更多