对于每个循环和多个范围
我有一个颜色编码的表格。 我想循环遍历每一行,并返回一个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
注意:
我已经注意到与Tally
variables相关的代码块有几个错误:
-
Tally
是一个stringvariables。 不要使用关键字Set
来分配一个stringvariables。 -
Tally
是一个stringvariables,因此Is Nothing
不匹配的。 检查Tally = vbNullString
或Len(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