【问题标题】:Stuck in a infinite loop陷入无限循环
【发布时间】:2020-05-13 09:01:13
【问题描述】:

如果输入数据符合某些条件,则需要打印出一个值的自动宏。我遇到的问题是它陷入了无限循环并且不会进入下一行。我是做循环的新手,所以欢迎任何建议或帮助。如果我尝试退出 for 它告诉我它无法识别下一个 else if 的 if 语句。

更新: 我已经按照建议清理了代码。 我在 .end(x1down) 中添加了但我得到一个应用程序定义或对象定义的错误 当我使用 .end(x1down).row 时,我得到的每个可能只能迭代一个集合对象或一个数组

我还不能发布图片,所以我将它们上传到 imgur 这里是显示输入数据示例的链接,图表数据来自https://imgur.com/a/3wiIX1t

Sub MonthCalc()

    Dim seat As Range
    Dim cfdp As Integer
    Dim si As Range
    Dim eqp As Range
    Dim leg As Range
    Dim result As String


    For Each seat In Range("e2").End(x1down).Row
        If seat.Value = 2 Then
            For Each si In Range("c2").End(x1down)
                If si.Value >= 0 And si.Value <= 359 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b5").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c5").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d5").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e5").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f5").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g5").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h5").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 400 And si.Value <= 459 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b6").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c6").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d6").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e6").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f6").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g6").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h6").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 500 And si.Value <= 559 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b7").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c7").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d7").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e7").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f7").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g7").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h7").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 600 And si.Value <= 659 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b8").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c8").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d8").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e8").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f8").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g8").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h8").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 700 And si.Value <= 1159 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b9").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c9").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d9").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e9").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f9").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g9").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h9").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 1200 And si.Value <= 1259 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b10").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c10").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d10").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e10").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f10").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g10").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h10").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 1300 And si.Value <= 1659 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b11").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c11").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d11").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e11").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f11").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g11").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h11").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 1700 And si.Value <= 2159 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b12").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c12").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d12").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e12").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f12").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g12").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h12").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 2200 And si.Value <= 2259 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = " 1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b13").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c13").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d13").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e13").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f13").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g13").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h13").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg

                ElseIf si.Value >= 2300 And si.Value <= 2359 Then
                    For Each leg In Range("f2").End(x1down)
                        If leg.Value = "1" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b14").Value
                        ElseIf leg.Value = "2" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c14").Value
                        ElseIf leg.Value = "3" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d14").Value
                        ElseIf leg.Value = "4" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e14").Value
                        ElseIf leg.Value = "5" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("f14").Value
                        ElseIf leg.Value = "6" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("g14").Value
                        ElseIf leg.Value = "7" Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("h14").Value
                        End If
                        Range("g:g") = cfdp
                    Next leg
                End If
            Next si

        ElseIf seat.Value = 3 Then
            For Each eqp In Range("b:b")
                If eqp.Value = 330 Or eqp.Value = 767 Then
                    For Each si In Range("c2").End(x1down)
                        If si.Value >= 0 And si.Value <= 559 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d18").Value
                        ElseIf si.Value >= 600 And si.Value <= 659 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d19").Value
                        ElseIf si.Value >= 700 And si.Value <= 1259 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d20").Value
                        ElseIf si.Value >= 1300 And si.Value <= 1659 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d21").Value
                        ElseIf si.Value >= 1700 And si.Value <= 2359 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("d22").Value
                        End If
                        Range("g:g") = cfdp
                    Next si

                ElseIf eqp.Value = 777 Or eqp.Value = 787 Then
                    For Each si In Range("c2").End(x1down)
                        If si.Value >= 0 And si.Value <= 559 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b18").Value
                        ElseIf si.Value >= 600 And si.Value <= 659 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b19").Value
                        ElseIf si.Value >= 700 And si.Value <= 1259 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b20").Value
                        ElseIf si.Value >= 1300 And si.Value <= 1659 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b21").Value
                        ElseIf si.Value >= 1700 And si.Value <= 2359 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("b22").Value
                        End If
                        Range("g:g") = cfdp
                    Next si
                End If

            Next eqp
        ElseIf seat.Value = 4 Then
            For Each eqp In Range("b:b")
                If eqp.Value = 330 Or eqp.Value = 767 Then
                    For Each si In Range("c2").End(x1down)
                        If si.Value >= 0 And si.Value <= 559 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e18").Value
                        ElseIf si.Value >= 600 And si.Value <= 659 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e19").Value
                        ElseIf si.Value >= 700 And si.Value <= 1259 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e20").Value
                        ElseIf si.Value >= 1300 And si.Value <= 1659 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e21").Value
                        ElseIf si.Value >= 1700 And si.Value <= 2359 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("e22").Value
                        End If
                    Next si

                ElseIf eqp.Value = 777 Or eqp.Value = 787 Then
                    For Each si In Range("c2").End(x1down)
                        If si.Value >= 0 And si.Value <= 559 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c18").Value
                        ElseIf si.Value >= 600 And si.Value <= 659 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c19").Value
                        ElseIf si.Value >= 700 And si.Value <= 1259 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c20").Value
                        ElseIf si.Value >= 1300 And si.Value <= 1659 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c21").Value
                        ElseIf si.Value >= 1700 And si.Value <= 2359 Then
                            cfdp = ThisWorkbook.Sheets("FAR117Chart").Range("c22").Value
                        End If
                        Range("g:g") = cfdp
                    Next si

                End If
            Next eqp
        End If
    Next seat
End Sub

【问题讨论】:

  • 你可能想要一个循环。另外,不要循环遍历整个列。有关如何找到最后一个单元格的信息,请参阅this question。这么多级别的缩进(和循环)是一种代码味道。
  • 您可以发送您的工作簿吗?当您手头有工作簿时,调试会容易得多。
  • 用文字解释你想用你的数据做什么会很有帮助。这段代码可能会更短。
  • @RossSymonds 试图找到一种方法来发布 excel 文件但无法下班
  • ElseIf si.Value &gt;= 400 Then: If si.Value &lt;= 459 Then - 为什么这不仅仅是ElseIf si.Value &gt;= 400 And si.Value &lt; 460 Then - 不必要的缩进要少得多,更容易阅读。您可能还想阅读Select Case statements

标签: excel vba for-loop


【解决方案1】:

另一种结合选择和 if 语句的替代方法:

也未经测试。如果你发布一些示例数据会更容易调试。

无论哪种方式,您都可以按 F8 并单步执行代码以查看逻辑是否正常工作。

编辑: 座位 = 3 时的调整案例(座位 = 4 请检查我如何编码之前的案例)

Public Sub MonthCalc()

    ' Define objects
    Dim sourceSheet As Worksheet
    Dim chartSheet As Worksheet
    Dim evalCell As Range

    ' Define other variables
    Dim lastRow As Long
    Dim chartColumn As Long
    Dim chartRow As Long

    Set sourceSheet = ThisWorkbook.Sheets("Sheet1")
    Set chartSheet = ThisWorkbook.Sheets("FAR117Chart")

    lastRow = sourceSheet.Range("E2").End(xlDown).Row

    For Each evalCell In Range("E2:E" & lastRow).Cells


        If evalCell.Value = 2 Then

            ' Get the offset column in column F
            chartColumn = evalCell.Offset(0, 1).Value - 1

            Select Case evalCell.Offset(0, -2).Value
            ' Column e = 2, c >= 0, c <= 359
            Case 0 To 359
                chartRow = 5
            ' Column e = 2, c >= 400, c <=459
            Case 400 To 459
                chartRow = 6
            ' Column e = 2, c >= 500, c <=559
            Case 500 To 559
                chartRow = 7
            ' Column e = 2, c >= 600, c <=659
            Case 600 To 659
                chartRow = 8
            ' Column e = 2, c >= 700, c <=1159
            Case 700 To 1159
                chartRow = 9
            ' Column e = 2, c >= 1200, c <=1259
            Case 1200 To 1259
                chartRow = 10
            ' Column e = 2, c >= 1300, c <=1659
            Case 1300 To 1659
                chartRow = 11
            ' Column e = 2, c >= 1700, c <=2159
            Case 1700 To 2159
                chartRow = 12
            ' Column e = 2, c >= 2200, c <=2259
            Case 2200 To 2259
                chartRow = 13
            ' Column e = 2, c >= 2300, c <=2359
            Case 2300 To 2359
                chartRow = 14
            End Select

        ElseIf evalCell.Value = 3 Then

            ' Column e = 3, b >= 330, b <=767
            If evalCell.Offset(0, -3).Value = 330 Or evalCell.Offset(0, -3).Value = 767 Then

                ' Get the offset column in column D
                chartColumn = 2

                Select Case evalCell.Offset(0, -2).Value
                Case 0 To 559
                    chartRow = 18
                Case 600 To 659
                    chartRow = 19
                Case 700 To 1259
                    chartRow = 20
                Case 1300 To 1659
                    chartRow = 21
                Case 1700 To 2359
                    chartRow = 22
                End Select

            ' Column e = 3, b >= 777, b <=787
            ElseIf evalCell.Offset(0, -3).Value = 777 Or evalCell.Offset(0, -3).Value = 787 Then

                ' Get the offset column in column D
                chartColumn = 0

                Select Case evalCell.Offset(0, -2).Value
                Case 0 To 559
                    chartRow = 18
                Case 600 To 659
                    chartRow = 19
                Case 700 To 1259
                    chartRow = 20
                Case 1300 To 1659
                    chartRow = 21
                Case 1700 To 2359
                    chartRow = 22
                End Select

            End If

        ElseIf evalCell.Value = 4 Then

            ' Add conditionals

        End If

        'Cell G in the same line
        evalCell.Offset(0, 2).Value = chartSheet.Range("B5").Offset(chartRow, chartColumn).Value

    Next evalCell

End Sub

如果有帮助,请告诉我。

【讨论】:

  • 这有效,除了当它检查座位 3 和 4 时没有打印出来/跨度>
【解决方案2】:

编辑:由于您的数据位于工作表上,因此您无需在 VBA 中对范围值进行编码:只需直接从表中查找数据即可。这是基于您的屏幕截图的示例:

'check a time value against the first column of a table where
'  values are of the form xxxx-xxxx: when matched return
'  the value from column number colNum
Function TimeLookup(tm, rng As Range, colNum As Long)
    Dim rw As Range, data, arr, r As Long, v, rv, ok As Boolean
    data = rng.Value
    For r = 1 To UBound(data, 1)
        v = data(r, 1)
        If InStr(v, "-") > 0 Then
            arr = Split(v, "-")
            If tm >= CLng(arr(0)) And tm <= CLng(arr(1)) Then
                rv = data(r, colNum)
                ok = True
                Exit For
            End If
        End If
    Next r
    'return the found value of #N/A if not match
    TimeLookup = IIf(ok, rv, CVErr(xlErrNA))
End Function

以下是关于如何处理此问题的未经测试且不完整的建议:

Sub MonthCalc()

    Dim ws As Worksheet, rw As Range, iblank As Long

    Set ws = ActiveSheet

    Set rw = ws.Range("A2:J2") ' start on (eg) row 2 of your data

    'keep processing until we've had (eg) 10 consecutive empty rows
    Do While iblank < 10

        If Application.CountA(rw) > 0 Then

            ProcessRow rw 'process this row

            iblank = 0 'reset blank count
        Else
            iblank = iblank + 1 'increment blank count
        End If

        Set rw = rw.Offset(1, 0) 'next row
    Loop

End Sub

Sub ProcessRow(rw As Range)
    Dim wsFar As Worksheet
    Dim seat, si, leg, eqp, rw As Long

    Set wsFar = ThisWorkbook.Worksheets("FAR117Chart")

    eqp = rw.Cells(1, "B").Value
    seat = rw.Cells(1, "E").Value
    si = rw.Cells(1, "C").Value
    leg = rw.Cells(1, "F").Value

    'check we have numeric values
    If OKnumber(seat) And OKnumber(si) And OKnumber(leg) Then
        If leg >= 1 And leg <= 7 Then
            'case where seat=2
            If seat = 2 Then
                rw = 0
                Select Case True
                    Case (si >= 0 And si <= 359): rw = 5
                    Case (si >= 400 And si <= 459): rw = 6
                    Case (si >= 500 And si <= 559): rw = 7
                    Case (si >= 600 And si <= 659): rw = 8
                    Case (si >= 700 And si <= 1159): rw = 9
                    Case (si >= 1200 And si <= 1259): rw = 10
                    Case (si >= 1300 And si <= 1659): rw = 11
                    Case (si >= 1700 And si <= 2159): rw = 12
                    Case (si >= 2200 And si <= 2259): rw = 13
                    Case (si >= 2300 And si <= 2359): rw = 14
                End Select

                If rw <> 0 Then
                    rw.Cells(1, "G").Value = wsFar.Cells(rw, 1).Offset(0, leg).Value
                End If
            End If

            'handle other seat values....


        End If
    End If
End Sub

'check if a value is no-blank and numeric: cast to long if yes
Function OKnumber(ByRef v) As Boolean
    Dim rv As Boolean
    rv = Len(v) > 0 And IsNumeric(v)
    If rv Then v = CLng(v) 'convert argument to long if numeric
    OKnumber = rv
End Function

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-03-17
  • 2021-02-15
  • 2022-01-23
  • 2021-01-23
  • 2015-04-02
相关资源
最近更新 更多