当前位置: 首页 > 知识库问答 >
问题:

无休止的VBA循环,除非我单步执行代码

陈扬
2023-03-14

我有一个包含6个列表对象的userform。所有列表对象都已命名range RowSources。单击任何一个列表中的任何一个项目都将引用电子表格上的图表,并清除任何项目单元格中不属于所选内容的内容(如果您感兴趣,请在下面进行更好的解释)。我的所有列表对象只有“更新后”触发器,其他的都由私有子程序处理。

不管怎么说,有很多列表之间的循环和跳转。如果我正常运行userform,它会无休止地循环。它似乎运行了一次,然后就像用户再次单击列表中的同一项一样,一次又一次。

奇怪的是,如果我单步执行代码(F8),它会完美地结束,当它应该这样做并且控制权返回给用户时。

有没有人想过为什么会这样?

编辑:我最初没有发布代码,因为它基本上都是一个循环,有150多行。我不明白,如果单步执行使其工作完美,但允许其正常运行使其无休止地循环,那么它怎么会是代码。总之,代码如下:

Option Explicit
    Dim arySelected(6) As String
    Dim intHoldCol As Integer, intHoldRow As Integer
    Dim strHold As String
    Dim rngStyleFind As Range, rngStyleList As Range

Private Sub UserForm_Activate()
    Set rngStyleList = Range("Lists_W_Style")
    Set rngStyleFind = Range("CABI_FindStyle")
End Sub
Private Sub lstStyle_AfterUpdate()
    If lstStyle.ListIndex >= 0 Then
        arySelected(0) = lstStyle.Value
        Call FilterCabinetOptions(Range("Lists_W_Style"), Range("CABI_FindStyle"), 0)
    End If
End Sub
Private Sub lstWood_AfterUpdate()
    If lstWood.ListIndex >= 0 Then
        arySelected(1) = lstWood.Value
        Call FilterCabinetOptions(Range("Lists_W_Wood"), Range("CABI_FindWood"), 1)
'        lstWood.RowSource = "Lists_W_Wood"
    End If
End Sub
Private Sub cmdReset_Click()
    Range("Lists_S_Style").Copy Destination:=Range("Lists_W_Style")
    Call RemoveXes(Range("Lists_W_Style"))
    Range("Lists_S_Wood").Copy Destination:=Range("Lists_W_Wood")
    Call RemoveXes(Range("Lists_W_Wood"))
    Range("Lists_S_Door").Copy Destination:=Range("Lists_W_Door")
    Call RemoveXes(Range("Lists_W_Door"))
    Range("Lists_S_Color").Copy Destination:=Range("Lists_W_Color")
    Call RemoveXes(Range("Lists_W_Color"))
    Range("Lists_S_Glaze").Copy Destination:=Range("Lists_W_Glaze")
    Call RemoveXes(Range("Lists_W_Glaze"))
    Range("Lists_S_Const").Copy Destination:=Range("Lists_W_Const")
    Call RemoveXes(Range("Lists_W_Const"))
    Range("Lists_S_DrawFrontConst").Copy Destination:=Range("Lists_W_DrawFrontConst")
    Call RemoveXes(Range("Lists_W_DrawFrontConst"))
End Sub
Private Sub FilterCabinetOptions(rngList As Range, rngFind As Range, intAry As Integer)
    Dim intListCntr As Integer, intFindCntr As Integer, intStyleCntr As Integer
    If intAry = 0 Then
        Call FindStyle(arySelected(intAry))
    Else
        'Save the List item.
        For intListCntr = 1 To rngList.Rows.Count
            If rngList.Cells(intListCntr, 1) = arySelected(intAry) Then
                rngList.Cells(intListCntr, 3) = "X"
'                Call RemoveNonXes(rngList)
                Exit For
            End If
        Next intListCntr
        'Save the column of the Find List.
        For intFindCntr = 1 To rngFind.Columns.Count
            If rngFind.Cells(1, intFindCntr) = arySelected(intAry) Then
                'Minus 2 to allow for columns A and B when using Offset in the below loop.
                intHoldCol = rngFind.Cells(1, intFindCntr).Column - 2
                Exit For
            End If
        Next intFindCntr
        'Find appliciple styles.
        For intStyleCntr = 1 To rngStyleFind.Rows.Count
            If Len(rngStyleFind.Cells(intStyleCntr, intHoldCol)) > 0 Then
                Call FindStyle(rngStyleFind.Cells(intStyleCntr, 1))
            End If
        Next intStyleCntr
    End If
    Call RemoveNonXes(rngStyleList)
    Call RemoveNonXes(Range("Lists_W_Wood"))
    Call RemoveNonXes(Range("Lists_W_Door"))
    Call RemoveNonXes(Range("Lists_W_Color"))
    Call RemoveNonXes(Range("Lists_W_Glaze"))
    Call RemoveNonXes(Range("Lists_W_Const"))
    Call RemoveNonXes(Range("Lists_W_DrawFrontConst"))
End Sub
Private Sub FindStyle(strFindCode As String)
    Dim intListCntr As Integer, intFindCntr As Integer
    For intListCntr = 1 To rngStyleList.Rows.Count
        If rngStyleList.Cells(intListCntr, 1) = strFindCode Then
            rngStyleList.Range("C" & intListCntr) = "X"
            Exit For
        End If
    Next intListCntr
    For intFindCntr = 1 To rngStyleFind.Rows.Count
        If rngStyleFind.Cells(intFindCntr, 1) = strFindCode Then
            intHoldRow = rngStyleFind.Cells(intFindCntr).Row
            Exit For
        End If
    Next intFindCntr
    If Len(arySelected(1)) = 0 Then Call FindStyleOptions(Range("CABI_FindWood"), Range("Lists_W_Wood"))
    If Len(arySelected(2)) = 0 Then Call FindStyleOptions(Range("CABI_FindDoor"), Range("Lists_W_Door"))
    If Len(arySelected(3)) = 0 Then Call FindStyleOptions(Range("CABI_FindColor"), Range("Lists_W_Color"), Range("Lists_W_Wood"))
    If Len(arySelected(4)) = 0 Then Call FindStyleOptions(Range("CABI_FindGlaze"), Range("Lists_W_Glaze"), Range("Lists_W_Wood"))
    If Len(arySelected(5)) = 0 Then Call FindStyleOptions(Range("CABI_FindConst"), Range("Lists_W_Const"))
    If Len(arySelected(6)) = 0 Then Call FindStyleOptions(Range("CABI_FindDrawFrontConst"), Range("Lists_W_DrawFrontConst"))
End Sub
Private Sub FindStyleOptions(rngFind As Range, rngList As Range, Optional rngCheckList As Range)
    Dim intListCntr As Integer, intFindCntr As Integer
    Dim intStrFinder As Integer, intCheckCntr As Integer
    Dim strHoldCheck As String
    Dim strHoldFound As String, strHoldOption As String
    'Go through the appropriate find list (across the top of CABI)
    For intFindCntr = 1 To rngFind.Columns.Count
        strHoldOption = rngFind.Cells(1, intFindCntr)
        strHoldFound = rngFind.Cells(1, intFindCntr).Offset((intHoldRow - 1), 0)
        If Len(strHoldFound) > 0 Then
            If rngCheckList Is Nothing Then
                For intListCntr = 1 To rngList.Rows.Count
                    If rngList.Cells(intListCntr, 1) = strHoldFound Then
                        Call AddXes(rngList, strHoldFound, "X")
                        Exit For
                    End If
                Next intListCntr
            Else
                intStrFinder = 1
                Do While intStrFinder < Len(rngFind.Cells(1, intFindCntr).Offset((intHoldRow - 1), 0))
                    strHoldCheck = Mid(rngFind.Cells(1, intFindCntr).Offset((intHoldRow - 1), 0), intStrFinder, 2)
                    intStrFinder = intStrFinder + 3
                    For intCheckCntr = 1 To rngCheckList.Rows.Count
                        If strHoldCheck = rngCheckList(intCheckCntr, 1) And Len(rngCheckList(intCheckCntr, 3)) > 0 Then
                            Call AddXes(rngList, strHoldOption, "X")
                            intStrFinder = 99
                            Exit For
                        End If
                    Next intCheckCntr
                Loop
            End If
        End If
    Next intFindCntr
End Sub
Private Sub AddXes(rngList As Range, strToFind As String, strX As String)
    Dim intXcntr As Integer
    For intXcntr = 1 To rngList.Rows.Count
        If rngList.Cells(intXcntr, 1) = strToFind Then
            rngList.Cells(intXcntr, 3) = strX
            Exit For
        End If
    Next intXcntr
End Sub
Private Sub RemoveNonXes(rngList As Range)
    Dim intXcntr As Integer
    For intXcntr = 1 To rngList.Rows.Count
        If Len(rngList(intXcntr, 3)) = 0 Then
            rngList.Range("A" & intXcntr & ":B" & intXcntr) = ""
        Else
            rngList.Range("C" & intXcntr) = ""
        End If
    Next intXcntr
End Sub
Private Sub RemoveXes(rngList As Range)
    rngList.Range("C1:C" & rngList.Rows.Count) = ""
End Sub

共有1个答案

孙修贤
2023-03-14

没有看到代码就很难分辨。当您运行脚本时,'AfterUpdate'事件可能会被反复触发,从而导致无休止的循环。尝试使用计数器将更新限制为一个更改,并在计数器大于0时退出循环

 类似资料:
  • 我有一段简单的代码,它应该是一个无休止的循环,因为将一直增长,并且始终大于。 但按原样,它打印并且不会无休止地循环。我想不出为什么。但是,当我以以下方式调整代码时: 它变成了一个无休止的循环,我不知道为什么。java是否认识到它是一个无休止的循环并在第一种情况下跳过它,但在第二种情况下必须执行一个方法调用,这样它的行为就像预期的那样?困惑:)

  • 问题在代码的注释中,很抱歉,我认为它更整洁,因为流程很重要,我想。。。 //*这是来自Oracle:(https://docs.oracle.com/javase/6/docs/api/java/util/Scanner.html#hasNextInt()) ”hasNextInt 公共布尔值hasnetint() 如果此扫描仪输入中的下一个标记可以使用nextInt()方法解释为默认基数中的in

  • 问题内容: 我有一段简单的代码,该代码 应该 是一个无休止的循环,因为它将一直在增长,并且始终会比更大。 但实际上,它可以打印并且不会无限循环。我不知道为什么。但是,当我以以下方式调整代码时: 这变成一个无尽的循环,我不知道为什么。java是否会识别出一个无穷循环并在第一种情况下跳过它,而在第二种情况下必须执行一个方法调用,以使其表现出预期的效果?困惑:) 问题答案: 这两个例子并不是无止境的。

  • 主要内容:循环控制语句当需要多次执行一段代码时,就可以使用循环语句。 一般来说,语句是按顺序执行的:函数中的第一个语句首先执行,然后是第二个,依此类推。 编程语言提供了各种控制结构,允许更复杂的执行路径。 循环语句允许多次执行语句或语句组。 以下是VBA中循环语句的一般形式。 VBA提供以下类型的循环来处理循环需求。点击以下链接查看详细信息。 编号 循环类型 描述 1 for循环 多次执行一系列语句,缩写管理循环变量的

  • 您的Google Maps代码结构如下所示: 回调? JavaScriptpromise? 您能想到的其他方法吗? 同样,这里所建议的信号量是一种可行的方法吗?

  • 我正在编写我自己的dns服务器(它接近pi hole项目,但有一些不同的/额外的功能),现在我面临着一个(对我来说)奇怪的问题: 基本上,我想做一个PTR请求IP到外部dns服务器(尝试208.67.222.222和8.8.8.8) 问题是,我最终陷入了一个无休止的循环,得到了一个SOA响应,其中主名称服务器与所请求的域相同(我想截图更精确) 但现实是这样的: