'For next' 循环在到达 'ubound' 之前重置计数器,导致无限循环...可能 name/reference 冲突?

'For next' loop resets counter before reaching 'ubound' resulting in infinite loop... possible name/reference clash?

我正在开发一个多千行程序,该程序 gathers/generates 一堆数据文件,所有格式都非常不同,然后收集(表格化)数据的一个子集并进行一些分析。

该程序几周前运行良好。现在,尽管没有触及它,但两次连续的测试运行和两次逐步调试会话已经进入无限期 for i = lbound(...) to ubound(...) .... next i loops。相关代码转载,如下。

显示的函数只是循环遍历二维数组(通过将范围分配给变体创建)以获取类似于一维数组中的字符串。导致错误的范围是 238x33。但是,"row" 索引 "i" 达到 44,然后重置回 0,而不是增加到 45 或更高。此外,当发生这种情况时,被 LIKE 反对的字符串会从“* example*”变为“** example**”,每次 "i" 计数器重置为 0 时,每边的星号数量都会增加。

我最好的猜测是存在某种 name/reference 冲突。但是,为什么现在才出现,而且还在猜测,我有点想不通。

函数定义:

Function arrayFirstLike(ByRef dataArr As Variant, ByVal fieldArr As Variant, _ 
Optional ByVal byRows As Boolean = True, Optional ByVal exactSearch As Boolean = False) As Variant

呼叫线路:

Set infowb = addSaveTemplate(rootPath & templatesPath & "\yFcstIndexInfo", rootPath & countryInfoPath & "\matureMarketFcst")
Set datawb = Workbooks.Open(rootPath & countryPath & "\spdjFcst", updateLinks:=False, ReadOnly:=True)
dataArr = datawb.Worksheets("ESTIMATES&PEs").UsedRange.Value
Call closeNoAlerts(datawb)

fieldArr = Array("Data as of the close of", "S&P 500 5YR")
fieldArr2 = arrayFirstLike(dataArr, fieldArr) 'returns 2x3 zero base array of variants

函数体(请注意,这是一个在程序其他地方成功调用的实用函数:因此,在嵌套循环开始之前,函数参数被重组):

Dim i As Long, j As Long, k As Long, fieldsFound As Long
Dim tempArr() As Variant

If Not IsArray(fieldArr) Then 'fieldArr is a single string
    fieldArr = Array(fieldArr)
Else
    On Error GoTo skipRedim
    i = LBound(fieldArr, 2)
    On Error GoTo 0

    ReDim tempArr(LBound(fieldArr, 1) To UBound(fieldArr, 1)) As Variant
    For i = LBound(tempArr, 1) To UBound(tempArr, 1)
        tempArr(i) = fieldArr(i, LBound(fieldArr, 2))
    Next i
    fieldArr = tempArr
afterRedim:
End If

If Not exactSearch Then
    For i = LBound(fieldArr, 1) To UBound(fieldArr, 1)
         fieldArr(i) = "*" & fieldArr(i) & "*"
    Next i
End If

ReDim tempArr(LBound(fieldArr, 1) To UBound(fieldArr, 1), 0 To 2) As Variant
fieldsFound = 0

If byRows Then
    For i = LBound(dataArr, 1) To UBound(dataArr, 1) 'rows
        For j = LBound(dataArr, 2) To UBound(dataArr, 2) 'cols
            For k = LBound(fieldArr, 1) To UBound(fieldArr, 1) 'searchlist
                If tempArr(k, 0) = Empty Then 'check for nonoccurance

                    If dataArr(i, j) Like fieldArr(k) Then 'k,1: seach string
                        tempArr(k, 0) = dataArr(i, j): tempArr(k, 1) = i: tempArr(k, 2) = j
                        fieldsFound = fieldsFound + 1
                        Exit For
                    End If

                End If
            Next k
            If fieldsFound = UBound(fieldArr, 1) - LBound(fieldArr, 1) + 1 Then Exit For
        Next j
        If fieldsFound = UBound(fieldArr, 1) - LBound(fieldArr, 1) + 1 Then Exit For
    Next i
Else
     For j = LBound(dataArr, 2) To UBound(dataArr, 2) 'cols
        For i = LBound(dataArr, 1) To UBound(dataArr, 1) 'rows
            For k = LBound(fieldArr, 1) To UBound(fieldArr, 1)
                If tempArr(k, 1) = Empty Then 'check first occurance

                    If dataArr(i, j) Like fieldArr(k) Then 'k,1: seach string
                        tempArr(k, 0) = dataArr(i, j): tempArr(k, 1) = i: tempArr(k, 2) = j
                        fieldsFound = fieldsFound + 1
                        Exit For
                    End If
                End If
            Next k
            If fieldsFound = UBound(fieldArr, 1) - LBound(fieldArr, 1) + 1 Then Exit For
        Next i
        If fieldsFound = UBound(fieldArr, 1) - LBound(fieldArr, 1) + 1 Then Exit For
    Next j
End If

arrayFirstLike = tempArr

Exit Function

skipRedim:
Resume afterRedim

这个怎么样:

On Error GoTo skipRedim
i = LBound(fieldArr, 2)
On Error GoTo 0

如果出现错误,您会跳到 afterRedim:,因此永远不会执行 On Error GoTo 0。这意味着以后的任何错误都将使用相同的错误处理程序,并且很容易导致您描述的行为。我会先尝试解决这个问题。

编辑:您可以创建一个函数来检查数组维度 - 请参阅此处答案中的示例 VBA check if array is one dimensional