处理VBA时出错(如果Err raise跳过此块)

时间:2017-12-20 11:56:06

标签: vba excel-vba error-handling excel

我是一名初学python程序员,但最近我在访问和excel中使用VBA编写了一些代码。

我正在使用一个代码从两个不同的查询中导出一些数据(从访问excel工作簿)。然后从excel继续对数据进行更多处理以进行一些销售分析。

问题在于,有时候,其中一个查询(或两者)都可以为空,这会引发

  

错误'3021'

我想做的是,如果

  

错误'3021'

发生在特定的块中,跳转到特定的行并继续执行。

在python中我会把那个代码块 - 我知道可以提高

  

错误'3021'

在“尝试”内部以避免执行

#code here
Try:
    #code that may raise error
Except Exception as '3021':
    pass
#code here....

在VBA中,我能够处理

  

错误'3021'

但不是我想要的。一旦我“管理”了

  

错误'3021'

如果其他代码中出现另一个错误,则最后一个错误处理程序始终处于活动状态(隐藏其他错误引发我想要调试的内容。代码的摘录是这样的:

On Error GoTo Err1Handler
'here starts the code that may raise the error '3021'
consulta16.MoveFirst
Datos16.Range("A2").CopyFromRecordset consulta16

With APIExcel.ActiveSheet.Cells
.Select
.EntireColumn.AutoFit
.Range("A1").Select
End With
'From here I know there wont be an error '3021'
NoData16:
columnas = consulta17.Fields.Count
For i = 0 To columnas - 1
    Datos17.Cells(1, i + 1) = consulta17.Fields(i).Name
Next i
'Now comes the second query that may raise same 
  

错误'3021'

所以我做了另一个错误异常

 On Error GoTo Err2Handler
 consulta17.MoveFirst
Datos17.Range("A2").CopyFromRecordset consulta17
    With APIExcel.ActiveSheet.Cells
    .Select
    .EntireColumn.AutoFit
    .Range("A1").Select
End With
'#more code.......
Err1Handler:
If Err.Number = 3021 Then
    'MsgBox ("Sin datos del 16")
    Resume NoData16
End If
Err2Handler:
If Err.Number = 3021 Then
        'MsgBox ("Sin datos del 17")
        Resume NoData17
End If

我看了here 这篇关于Vba中的错误处理的文档,但我不知道如何在不影响整个脚本的情况下处理特定错误。我想我正试图在python中面对vba错误处理...我会很感激,如果有人可以帮助我理解如何在不影响整个脚本的情况下隔离错误处理程序中的代码块(Try / Catch / Finally方式? )

3 个答案:

答案 0 :(得分:1)

我会这样做的:

选项明确

Public Sub TestMe()

    Dim a As Long
    Dim b As Long

    On Error GoTo TestMe_Error

    a = 1: b = 0
    Debug.Print a / b   'Error 11
    Debug.Print "Some more stuff..."
    Debug.Print a / b   'Error 11
    Debug.Print "Some other stuff..."        
    a = 0
    Debug.Print a / b   'Error 6

    On Error GoTo 0
    Exit Sub

TestMe_Error:
    If Err.Number = 11 Then
        Resume Next
    Else
        MsgBox Err.Number & " " & Err.Description
    End If
End Sub

因此,如果您查找错误11,它将忽略它并继续,并且将捕获所有其他错误(例如,捕获错误6)。

这是找到该行的方法,导致错误:

Public Sub TestMe()

    On Error GoTo TestMe_Error

    Debug.Print 3 / 4
    Debug.Print 4 / 0
    Debug.Print 6 / 1

    On Error GoTo 0
    Exit Sub

TestMe_Error:
    Stop
    Resume
End Sub

代码在Stop行停止后,如果按两次 F8 ,则会转到错误行。

答案 1 :(得分:0)

您应该能够使用一个主错误处理程序并捕获其中的不同代码和操作,并在适当处理后使用Err.Clear重置错误号。然后是关于何处返回的说明。

'Other code
Exit Sub

Err1Handler:

If Err.Number = 3021 Then

    'MsgBox ("Sin datos del 16")
    Err.Clear
    Resume NoData16

ElseIf Err.Number = X Then
    MsgBox "The workbook named """ & Bk & """ does not exist."
    Err.Clear
    'Resume Next  ''Example. Instruction on what to do next; where to go
End If

End Sub

或使用相同的想法,但

Select Case Err.Number
            Case 0

答案 2 :(得分:0)

我的处理方式有点不同。我的查询知识相当薄弱,但我相信同样的原则适用:

If (Test for a record) then
'Code here
Else
'Error Handling here
End if

这会得到相同的结果,而不会处理onerror - 因为如果你有更多的代码,并且你忘了关闭/更改它,你可以循环回到它而没有意义。我已经处理了足够的意大利面条代码,以便在我可以使用布尔值时避免出现错误。

当然,所有这些都假定您可以在运行查询之前测试记录是否存在。