为什么我的For Each循环仅迭代一次?

时间:2019-09-05 09:17:40

标签: excel vba

每个循环我都需要遍历整个范围。对于带有if语句的每个循环,我有三个循环,用于检查是否满足条件。但是,即使不满足条件,循环也只会迭代一次。子然后打破。

Set ServiceRNG = Dataworksheet.Range("U2").End(xlDown)
Set OldServiceNamesRNG1 = ProductOderingCodeWS.Range("B7").End(xlToRight)
Set OldServiceNamesRNG2 = ProductOderingCodeWS.Range("B8").End(xlToRight)
CounterSheet1 = 2
Set Nextcellvalue = Dataworksheet.Range("U" & CounterSheet1 + 1)
Set Productorderingcode = Dataworksheet.Range("U" & CounterSheet1).Offset(0, 5)

For Each ServiceName In ServiceRNG
    Nextcellvalue = Dataworksheet.Range("U" & CounterSheet1 + 1)
    If ServiceName.Value = Nextcellvalue.Value Then
        Productorderingcode = Dataworksheet.Range("U" & CounterSheet1).Offset(0, 5)
        Productorderingcode.Copy


    CounterDatabaseWS = 2
    For Each OldServiceName1 In OldServiceNamesRNG1
        If ServiceName.Value = OldServiceName1.Value Then
        ProductOderingCodeWS.Cells(Rows.Count, CounterDatabaseWS).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
        Exit For
        End If
        CounterDatabaseWS = CounterDatabaseWS + 1
    Next OldServiceName1

    CounterDatabaseWS = 2
    For Each OldServiceNames2 In OldServiceNamesRNG2
        If ServiceName.Value = OldServiceNames2.Value Then
        ProductOderingCodeWS.Cells(Rows.Count, CounterDatabaseWS).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
        Exit For
        End If
        CounterDatabaseWS = CounterDatabaseWS + 1
    Next OldServiceNames2

Else
    Productorderingcode = Dataworksheet.Range("U" & CounterDatabaseWS).Offset(0, 5).Value
    Productorderingcode.Copy
    ProductOderingCodeWS.Cells(Rows.Count, CounterDatabaseWS).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues

End If

CounterSheet1 = CounterSheet1 + 1
Next ServiceName

代码按预期运行,条件评估从范围的第一个索引开始,但不会遍历整个范围。在这种情况下,请使用ServiceRNG,OldeServiceNamesRNG1和OldeServiceNamesRNG2。

2 个答案:

答案 0 :(得分:3)

您的For Each循环仅迭代一次,因为代码行Set ServiceRNG = Dataworksheet.Range("U2").End(xlDown)只是获得了它找到的最后一个Range单元,而不是全部从单元格U2开始。

如果要选择它找到的所有值,请从此更改该行:

Set ServiceRNG = Dataworksheet.Range("U2").End(xlDown)

对此:

Set ServiceRNG = Dataworksheet.Range(Dataworksheet.Range("U2"), Dataworksheet.Range("U2").End(xlDown))

这将使For Each循环迭代到所有值。

当然,您必须对For Each循环中涉及的所有变量执行相同的操作。

希望这会有所帮助。

答案 1 :(得分:0)

这些行仅返回一个单元格!

Set ServiceRNG = Sheets(1).Range("U2").End(xlDown)
Set OldServiceNamesRNG1 = Sheets(1).Range("B7").End(xlToRight)
Set OldServiceNamesRNG2 = Sheets(1).Range("B8").End(xlToRight)

请参阅:selection of multiple columns with end(xlDown).End(xlUp).Row

或参见:https://www.excel-easy.com/vba/examples/from-active-cell-to-last-entry.html

您需要将其更改为:

Set ServiceRNG = ws1.Range(ws1.Range("U2"), ws1.Range("U2").End(xlDown))
Set OldServiceNamesRNG1 = ws1.Range(ws1.Range("B7"), ws1.Range("B7").End(xlToRight))
Set OldServiceNamesRNG2 = ws1.Range(ws1.Range("B8"), ws1.Range("B8").End(xlToRight))

您的if子句“ If ServiceName.Value = Nextcellvalue.Value Then”在第二和第三循环之后结束。这是故意的吗?

这是根据您的代码工作的MVE

Option Explicit

Sub test3Loops()

Dim ServiceRNG As Range
Dim OldServiceNamesRNG1 As Range
Dim OldServiceName1 As Range
Dim OldServiceNamesRNG2 As Range
Dim OldServiceNames2 As Range

Dim Nextcellvalue As Range
Dim Productorderingcode As Range
Dim ServiceName As Range

Dim CounterSheet1 As Integer
Dim CounterSheet2 As Integer
Dim Dataworksheet As Worksheet
Dim ProductOderingCodeWS As Worksheet
Dim ws1 As Worksheet

Set ws1 = Sheets(1)
'Set ProductOderingCodeWS = Sheets(2)

'Setup Data for ws1

'ServiceRNG
ws1.Range("U1") = "ServiceRNG"
ws1.Range("U2") = "A"
ws1.Range("U3") = "B"
ws1.Range("U4") = "C"

'OldServiceNamesRNG1
ws1.Range("B7") = "1"
ws1.Range("C7") = "2"
ws1.Range("D7") = "3"

'OldServiceNamesRNG2
ws1.Range("B8") = "X"
ws1.Range("C8") = "Y"
ws1.Range("D8") = "Z"

'ERROR: These lines give back only one cell!
'Set ServiceRNG = Sheets(1).Range("U2").End(xlDown)
'Set OldServiceNamesRNG1 = Sheets(1).Range("B7").End(xlToRight)
'Set OldServiceNamesRNG2 = Sheets(1).Range("B8").End(xlToRight)
'see: https://stackoverflow.com/questions/50370919/selection-of-multiple-columns-with-endxldown-endxlup-row
'see: https://www.excel-easy.com/vba/examples/from-active-cell-to-last-entry.html

Set ServiceRNG = ws1.Range(ws1.Range("U2"), ws1.Range("U2").End(xlDown))
Set OldServiceNamesRNG1 = ws1.Range(ws1.Range("B7"), ws1.Range("B7").End(xlToRight))
Set OldServiceNamesRNG2 = ws1.Range(ws1.Range("B8"), ws1.Range("B8").End(xlToRight))

CounterSheet1 = 2

'Set Nextcellvalue = Dataworksheet.Range("U" & CounterSheet1 + 1)
'Set Productorderingcode = Dataworksheet.Range("U" & CounterSheet1).Offset(0, 5)

For Each ServiceName In ServiceRNG
    Set Nextcellvalue = ws1.Range("U" & CounterSheet1 + 1)

'        If ServiceName.Value = Nextcellvalue.Value Then
'            Productorderingcode = Dataworksheet.Range("U" & CounterSheet1).Offset(0, 5)
'            Productorderingcode.Copy
'        'missing end if? You did include the 2nd and 3rd loop into the above if clause!
'        End If

    'CounterDatabaseWS = 2
    For Each OldServiceName1 In OldServiceNamesRNG1
'        If ServiceName.Value = OldServiceName1.Value Then
'            ProductOderingCodeWS.Cells(Rows.Count, CounterDatabaseWS).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
'        Exit For
'        End If
        Debug.Print "OldServiceName1 : "; ServiceName.Value & " - " & OldServiceName1.Value
    Next OldServiceName1

    'CounterDatabaseWS = 2
    For Each OldServiceNames2 In OldServiceNamesRNG2
'        If ServiceName.Value = OldServiceNames2.Value Then
'        ProductOderingCodeWS.Cells(Rows.Count, CounterDatabaseWS).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
'        Exit For
'        End If
        Debug.Print "OldServiceName2 : "; ServiceName.Value & " - " & OldServiceNames2.Value
    Next OldServiceNames2

    'Else
    '    Productorderingcode = Dataworksheet.Range("U" & CounterDatabaseWS).Offset(0, 5).Value
    '    Productorderingcode.Copy
    '    ProductOderingCodeWS.Cells(Rows.Count, CounterDatabaseWS).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues

    'End If

'CounterSheet1 = CounterSheet1 + 1
Next ServiceName

End Sub

立即窗口最终显示:

OldServiceName1 : A - 1
OldServiceName1 : A - 2
OldServiceName1 : A - 3
OldServiceName2 : A - X
OldServiceName2 : A - Y
OldServiceName2 : A - Z
OldServiceName1 : B - 1
OldServiceName1 : B - 2
OldServiceName1 : B - 3
OldServiceName2 : B - X
OldServiceName2 : B - Y
OldServiceName2 : B - Z
OldServiceName1 : C - 1
OldServiceName1 : C - 2
OldServiceName1 : C - 3
OldServiceName2 : C - X
OldServiceName2 : C - Y
OldServiceName2 : C - Z