对于每个循环和多个范围

我有一个颜色编码的表格。 我想循环遍历每一行,并返回一个string,表示该行中的哪些列被着色。 我的方法是定义要循环的单元格的垂直范围,然后为该范围中的每个单元格定义一个循环的水平范围。 我得到的错误说Forvariables已经在使用中了。 这是我正在使用的代码:

Public Sub Months() Dim Tally As String Dim R1 As Range Dim R2 As Range Dim Col As String Range("A2").Select Range(Selection, Selection.End(xlDown)).Select Set R1 = Range(Selection.Address) For Each cell In R1 cell.Activate Range(Selection, Selection.End(xlRight)).Select Set R2 = Range(Selection.Address) For Each cell In R2 If cell.Interior.ColorIndex > 0 Then Col = Split(ActiveCell(1).Address(1, 0), "$")(0) If Tally Is Nothing Then Set Tally = Col Else Set Tally = Tally + ";" + Col End If Range("DF" & (ActiveCell.Row)).Select ActiveCell.Value = Tally End If Next Next End Sub 

有什么想法吗?

非常感谢。

与往常一样, Option Explicit将帮助您识别此错误的原因。

对于初学者来说,你不需要多个范围,只需要一个范围来定义整个表格。 下面我会告诉你如何做到这一点。

至于直接的问题

在上下文中, For each cell in ... R1中的For each cell in ... R1其中cell不是特殊关键字,它是正在使用的隐含variables。 当你稍后做的时候For each cell in R2由于cell循环已经启动,所以上面的Excel会对你有所帮助。

也就是说,如果我们使用伪关键字cell以外的东西,问题可能会更加明显:

 For i = 1 to 10 For i = 3 to 44 Msgbox i Next Next 

如果编译器能够到达消息框行, i希望它显示什么值? 这是错误的原因。 你的迭代器已经被使用了,你不能重复使用它。

声明所有的variables,并使用Option Explicit来避免将来的这些错误:)

定义表格范围的更好的方法

但是,简单地定义一个范围会更有效率,而不是随意地尝试为表格中的每一行或每列定义和重新定义行范围。 尝试这样的事情。

 Option Explicit Public Sub Months() Dim Tally As String Dim tbl As Range Dim r As Range Dim c As Range Dim cl As Range Dim Col As String Set tbl = Range(Range("A2").End(xlDown), Range("A2").End(xlToRight)) For Each r In tbl.Rows For Each c In tbl.Columns Set cl = tbl.Cells(r, c) If cl.Interior.ColorIndex > 0 Then Col = Split(cl.Address(1, 0), "$")(0) ' If Tally Is Nothing Then ' Set Tally = Col ' Else ' Set Tally = Tally + ";" + Col ' End If Range("DF" & (cl.Row)).Select cl.Value = Tally End If Next Next End Sub 

注意:

我已经注意到与Tallyvariables相关的代码块有几个错误:

  • Tally是一个stringvariables。 不要使用关键字Set来分配一个stringvariables。
  • Tally是一个stringvariables,因此Is Nothing不匹配的。 检查Tally = vbNullStringLen(Tally) = 0
  • 虽然运算符+可能允许string连接,但我相信VBA中的首选运算符是& ,所以虽然这可能不会导致错误,但是您可能会为了消除歧义而改变它。

您在嵌套的For循环中使用相同的variables名称:

 For Each cell In R1 ... For Each cell In R2 

将第二个循环中的“单元格”variables改为别的。

另外,这一行:

 If Tally Is Nothing Then 

将打破。 理货被定义为一个string,而不是一个对象,所以你应该使用“如果理货”>“然后”

如果可能的话,你应该避免做出select。

未经testing:

 Public Sub Months() Dim Tally As String Dim R1 As Range Dim R2 As Range Dim Col As String Dim c As Range, c2 As Range With ActiveSheet Set R1 = .Range(.Range("A2"), .Range("A2").End(xlDown)) End With For Each c In R1.Cells Tally = "" Set R2 = ActiveSheet.Range(c, c.End(xlToRight)) 'not xlRight... For Each c2 In R2.Cells If c2.Interior.ColorIndex > 0 Then Col = Split(c2.Address(), "$")(0) Tally = Tally & IIf(Len(Tally) > 0, ";", "") & Col 'Set not required... End If Next ActiveSheet.Range("DF" & c.Row).Value = Tally Next End Sub