【问题标题】:What is the proper way to add retry loop to VBA code将重试循环添加到 VBA 代码的正确方法是什么
【发布时间】:2021-04-16 23:16:07
【问题描述】:

在下面的代码中,我们偶尔会遇到碰撞错误。如果它等待一秒钟然后重试,它就会通过。

我希望它尝试一次。如果失败,请记录错误并重试。如果失败 3 次,MsgBox 给用户,放弃并返回。我能想到的唯一方法是使用 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

【问题讨论】:

    标签: vba ms-access vba7


    【解决方案1】:

    大概是这样的……

        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
    

    【讨论】:

    • 这些都是很好的答案。我更喜欢这个,因为我认为它更清晰,更容易阅读。将执行分离到它自己的函数中允许您使用内置的错误处理并仍然围绕它包装逻辑。
    【解决方案2】:

    考虑使用在尝试次数达到最大时结束的 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-30
      • 2010-11-07
      • 1970-01-01
      • 2016-11-09
      • 2023-04-09
      • 1970-01-01
      • 2020-02-15
      • 1970-01-01
      相关资源
      最近更新 更多