遍历`Range`中的`Cells`

问题的简短版本

这里的代码

Dim rng As Range Set rng = Selection Set rng = rng.Columns(1) For Each cl In rng cl.Select ' <-- Break #2 

当select是A1:B37时,在即时窗口给我这个

 ? rng.address(External:=True) [Book2]Sheet1!$A$1:$A$37 ? cl.Address(External:=True) [Book2]Sheet1!$A$1:$A$37 

任何人都可以帮助我理解为什么cl -> A1:A37而不是cl -> A1请注意,我想象重写代码来获得预期的结果。 但是我想知道这个问题是什么,也许会学到一些新的东西。 这就是问题所在。


问题的长版(原贴)

我有一个子程序,它在选定的(矩形)范围rng 。 这里的相关代码如下所示。 它根据rng列的数量ncols分支。

ncols=1 ,它循环遍历每个单元格cl ,selectcl并执行一些操作。 当起始select是A1:A37 ,这可以正常工作,正如立即窗口中的输出所示,在进入1号断点处的循环之后(见下面的代码)

 ? rng.address(External:=True) [Book2]Sheet1!$A$1:$A$37 ? cl.Address(External:=True) [Book2]Sheet1!$A$1 

ncols<>1 ,我想循环遍历rng 第一列中的每个单元格cl ,与之前一样。 现在,当起始select是A1:B37 ,这不起作用,如Break#2的立即窗口中的输出所示

 ? rng.address(External:=True) [Book2]Sheet1!$A$1:$A$37 ? cl.Address(External:=True) [Book2]Sheet1!$A$1:$A$37 

任何人都可以帮助我理解为什么在这里cl -> A1:A37而不是cl -> A1 (如在第一次rest )? 请注意,我想象重写代码来获得预期的结果。 但是我想知道这个问题是什么,也许会学到一些新的东西。 这就是问题所在。

 Dim rng As Range Set rng = Selection Dim ncols As Long ncols = rng.Columns.Count Dim cl As Range ' 1- If only one column is selected, ... If (ncols = 1) Then For Each cl In rng cl.Select ' <-- Break #1 ... Next cl ' 2- If more than one column is selected, ... Else Set rng = rng.Columns(1) For Each cl In rng cl.Select ' <-- Break #2 Dim rng2 As Range Set rng2 = Range(cl, cl.Offset(0, ncols - 1)) rng2.Select ... Next cl End If 

我还没有机会testing你的代码,但你可能只是缺乏明确性: cl是一个Range ,所以是一个Column和一个Row ,一个Area和任何其他types的范围types的对象。 你可以像cl一样使用范围迭代器: For each cl in Rng.Rows或者...in rng.Columns或者...rng.Cells等等

换句话说,虽然你可能希望将cl作为一个单元格范围,但除非明确说明,否则情况可能并非如此:

 For each cl in rng.Cells 

或者,由于您将其定义为单列,因此这将是等同的:

 For Each cl in rng.Rows 

(从技术上讲, cl表示rng范围,但由于是单列范围,所以每个“行”也是单个单元格)。

你的代码可以相当精简:

 Sub f() Dim rng As Range Dim cl As Range Dim rng2 As Range Set rng = Range(Selection.Address).Resize(, 1) ncols = Range(Selection.Address).Columns.Count For Each cl In rng.Cells cl.Select ' <-- Break #2 If nCols > 1 Then Set rng2 = Range(cl, cl.Offset(0, ncols - 1)) rng2.Select '... End If Next cl End Sub