我有一张颜色编码的表格。我想循环遍历每一行,并返回一个字符串,表示该行中哪些列是彩色的。我的方法是定义一个垂直的单元格循环,然后为该范围内的每个单元格定义一个循环的水平范围。我得到的错误说For变量已经在使用中。这是我正在使用的代码:
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
有什么想法吗?
非常感谢。
答案 0 :(得分:2)
与往常一样,Option Explicit
将帮助您确定此错误的原因。
对于初学者,您不需要多个范围,只需要一个范围来定义整个表。我将在下面告诉你如何做到这一点。
至于即时问题:
在上下文中,For each cell in ... R1
cell
不是特殊关键字,它是正在使用的隐含变量。当您稍后执行For each cell in R2
时,Excel会向您发出警告,因为cell
循环已在上面启动。
即,如果我们使用伪关键字cell
以外的其他内容,问题就更明显了:
For i = 1 to 10
For i = 3 to 44
Msgbox i
Next
Next
如果编译器可以进入消息框行,您希望它显示的i
值是多少?这是错误的原因。您的迭代器已在使用中,您无法重复使用它。
声明所有变量,并使用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
变量相关的代码块,因为有几个错误:
Tally
是一个字符串变量。不要使用关键字Set
来分配字符串变量。Tally
是一个字符串变量,因此Is Nothing
将不匹配。请检查Tally = vbNullString
或Len(Tally) = 0
。+
可能允许字符串连接,但我相信VBA中的首选运算符为&
,因此虽然这可能不会导致错误,但您可能会因为消除歧义而更改。答案 1 :(得分:1)
您在嵌套的For循环中使用相同的变量名称:
For Each cell In R1
...
For Each cell In R2
将第二个循环中的“cell”变量更改为其他内容。
此外,这一行:
If Tally Is Nothing Then
会破裂。 Tally被定义为String,而不是对象,因此您应该使用“If Tally<>”“Then”
答案 2 :(得分:1)
如果可能的话,你应该避免做出选择。
未测试:
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