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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了处理VBA时出错(如果Err raise跳过此块)相关的知识,希望对你有一定的参考价值。

我是一个初学的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方式? )

答案

我会这样做的:

选项明确

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,你会转到错误行。

另一答案

您应该能够使用一个主错误处理程序并捕获其中的不同代码和操作,并在适当处理后使用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
另一答案

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

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

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

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

以上是关于处理VBA时出错(如果Err raise跳过此块)的主要内容,如果未能解决你的问题,请参考以下文章

怎样让win10复制时出错不要停下了,自动跳过,或者有能实现的工具?

python3 异常处理

raise的使用

raise ValueError(err) - 在 Python 中使用 concurrent.future 实现多线程

Excel VBA代码无法保存

VBA 学习笔记 错误处理