Цикл Do Хотя не выходит из цикла x<y, несмотря на x>y

Извините за многословное название...

У меня есть (второй) цикл в длинном наборе кода VBA. Цикл такой:

Do While counterB < 40000
    On Error Resume Next
    AppActivate "Oracle Fusion Middleware Forms Services"
    If Err.Number <> 0 Then
        counterB = counterB + 100
        Sleep 100
    Else
        counterB = counterB + 40001
    End If
Loop

Теперь есть похожий цикл, который проверяет другую программу непосредственно перед этой, и она прекрасно работает. Проверяет, открыта ли программа, увеличивает ли ее счетчик (счетчики для двух циклов имеют разные имена), проверяет снова, увеличивает, промывает и повторяет, в конечном итоге находит свою программу, выходит из цикла и код VBA продолжается.

Но этот второй цикл... это просто цикл. Снова и снова... Он вступает в If/Else просто отлично (значит, он видит или не видит программу, вызываемую в AppActivate), ноWhile В заявлении не указано, что counterB больше 40000.

Кто-нибудь видит, что я сделал не так...? Заранее спасибо.

3 ответа

Решение

Просто чтобы объяснить integer вещи CLR и Jeeped говорят о:

Целое число в VBA составляет 2 байта и подписано (может иметь отрицательные значения), поэтому максимальное значение равно 32767. Если вы попытаетесь записать в него большее значение, вы получите ошибку времени выполнения 6 (переполнение), и значение останется неизменным. Как есть on error resume nextошибка не отображается, значение остается максимальным на уровне 32767 и никогда не достигает значения 40000 - вы попали в бесконечный цикл.

Если вам действительно нужно on error resume next в вашем коде вы должны проверить Err.Number для конкретных значений, которые вы ожидаете (и повторно вывести ошибку или показать MsgBox или что-то в этом роде).

Ваш код может выглядеть так:

Do While counterB < 40000
    Dim saveError As Long
    On Error Resume Next
    AppActivate "Oracle Fusion Middleware Forms Services"
    saveError = Err.Number
    On Error GoTo 0

    If saveError <> 0 Then
        If Err.Number = <ENTER YOUR SPECIFIC ERROR CODE> Then
            counterB = counterB + 100
            Sleep 100
        Else
            Err.Raise saveError
        End If
    Else
        counterB = counterB + 40001
    End If
Loop

В то время как обсуждение и принятый ответ объясняют, почему код OP потерпел неудачу, весь подход, принятый OP, не является идеальным.

Вот как бы я это сделал

Sub Demo()
    Dim saveError As Long
    Dim counterB As Long
    Dim AppActivated  As Boolean

    For counterB = 1 To 400
        On Error Resume Next
            AppActivate "Oracle Fusion Middleware Forms Services"
            saveError = Err.Number
        On Error GoTo 0

        If saveError = 0 Then
            AppActivated = True
            Exit For
        Else
            Select Case saveError
                '<ENTER YOUR SPECIFIC ERROR CODES HERE>
                Case 5, 6, 7 ' for example
                    Sleep 100
                Case Else
                    Err.Raise saveError
            End Select
        End If
    Next

    If Not AppActivated Then
        ' Loop timed out.  What Now?
    Else
        ' App is activated
        '  More code...
    End If
End Sub

Предполагая, как упоминал @Jeeped, counterB не является целым числом.. попробуйте следующее:

Do While counterB < 40000
    On Error Resume Next
    AppActivate "Oracle Fusion Middleware Forms Services"
    If Err.Number <> 0 Then
        counterB = counterB + 100
        Sleep 100
        Err.Clear
    Else
        counterB = counterB + 40001
    End If
Loop
Другие вопросы по тегам