对于每个循环和多个范围

时间:2013-06-07 17:33:45

标签: excel vba excel-vba

我有一张颜色编码的表格。我想循环遍历每一行,并返回一个字符串,表示该行中哪些列是彩色的。我的方法是定义一个垂直的单元格循环,然后为该范围内的每个单元格定义一个循环的水平范围。我得到的错误说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

有什么想法吗?

非常感谢。

3 个答案:

答案 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 = vbNullStringLen(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