将重试循环添加到 VBA 代码的正确方法是什么

What is the proper way to add retry loop to VBA code

在下面的代码中,我们偶尔会遇到碰撞错误。如果它稍等片刻并重试,它就会通过。

我想尝试一次。如果失败,请记录错误并重试。如果失败3次,MsgBox给用户,放弃并return。我能想到的唯一方法是使用 GOTO 返回到 ExeHandler。看来应该有更好的办法。

  Public Function RunADO(strContext As String, strSQL As String, Optional intErrSilent As Integer = 0, Optional intErrLog = -1) As Integer
  On Error GoTo ErrHandler
  ExeHandler:

     PostToLog strContext, "SQL: " & strSQL
     CurrentProject.Connection.Execute strSQL, dbFailOnError
     RunADO = -1
     Exit Function
  ErrHandler:
     RunADO = 0
     If intErrSilent = 0 Then
        MsgBox Err.Number & ": " & Err.Description, vbCritical, "Run ADO"
     End If
     If intErrLog = -1 Then
        PostErrorToLog Err.Number, strContext, Err.Source & ":" & Err.Description & ": " & "SQL: " & strSQL
     End If
  End Function

也许是这样的……

    Option Explicit

    Private Const MaxRetries As Long = 3

    Public Function RunADO(strContext As String, strSQL As String, Optional intErrSilent As Integer = 0, Optional intErrLog = -1) As Integer
        Dim attemptCounter As Long
        For attemptCounter = 1 To MaxRetries
            RunADO = RunADOInternal(strContext, strSQL, intErrSilent, intErrLog)
            If RunADO = -1 Then
                Exit Function
            End If
            If intErrSilent = 0 And attemptCounter >= MaxRetries Then
                MsgBox Err.Number & ": " & Err.Description, vbCritical, "Run ADO"
                RunADO = 0
                Exit Function
            End If
            If intErrLog = -1 Then
                PostErrorToLog Err.Number, strContext, Err.Source & ":" & Err.Description & ": " & "SQL: " & strSQL
            End If
            Application.Wait (Now + TimeValue("0:00:01"))
        Next attemptCounter
    End Function

    Private Function RunADOInternal(strContext As String, strSQL As String, Optional intErrSilent As Integer = 0, Optional intErrLog = -1) As Integer
      On Error GoTo ErrHandler

         PostToLog strContext, "SQL: " & strSQL
         CurrentProject.Connection.Execute strSQL, dbFailOnError
         RunADO = -1
         Exit Function
    ErrHandler:
         RunADO = 0
    End Function

考虑使用在达到最大尝试次数后结束的 Do / Loop 语句。

Public Function RunADO(strContext As String, _
                       strSQL As String, _
                       Optional intErrSilent As Integer, _
                       Optional intErrLog = -1) As Integer
  
    Dim Attempts As Integer
    
    Do While Attempts < 3
        On Error Resume Next
        PostToLog strContext, "SQL: " & strSQL
        CurrentProject.Connection.Execute strSQL, dbFailOnError
        If Err.Number Then
            If intErrSilent = 0 Then
               MsgBox Err.Number & ": " & Err.Description, vbCritical, "Run ADO"
            End If
            If intErrLog = -1 Then
               PostErrorToLog Err.Number, strContext, _
                              Err.Source & ":" & Err.Description & ": " & "SQL: " & strSQL
            End If
            Attempts = Attempts + 1
        Else
            RunADO = -1
            Exit Do
        End If
     Loop
  End Function