如果没有设置Label,VBA错误处理程序是否可以在With语句的开头恢复?
例如:
Dim rst As DAO.Recordset
Set rst = Nothing
On Error GoTo ErrHand
With rst
.AddNew
!MyValue = 1
.Update
.Bookmark = .LastModified
End With
ErrHand:
If Err.Number <> 0 Then
Call SetRST 'Assume this procedure opens the recordset appropriately
Resume
End If
End Sub()
代码将导致&#34; .AddNew&#34;行,然后当它通过错误处理程序将设置记录集,但然后它将恢复在&#34; .AddNew&#34;线。问题是它仍然在&#34; With&#34; CommentRST什么都不是的声明。有没有办法告诉错误处理程序在&#34;使用RST&#34;换行或者#34; .AddNew&#34;在&#34;&#34;之前没有创建标签的行声明或首先检查空白记录集?
我知道有很多方法可以解决这个问题(因为我刚刚建议其中2条),但我很好奇这是否可行。
答案 0 :(得分:4)
只需在SetRST中添加一个byRef参数。
例如:
Sub SetRST(byref myrs as recordset)
'do stuff
set myrs = ...
顺便提一下,您的错误处理示例很糟糕:只需在Exit Sub
之前添加ErrHand:
,
所以你不需要测试err.number<>0
,因为你知道它总是如此。
在错误处理中,请使用:
call SetRST rst
编辑:
我更喜欢这样的东西:
If rst Is Nothing Then
Set rst = something
End if
With rst
'continue here
答案 1 :(得分:3)
With
块包含对象的实例,并在End With
处释放它。如果你跳到With
区域之外,对象就会消失。
所以答案是否定的,你可以 你实际上可以,但是丑陋和混乱。 Resume
进入With
区块的中间。
这是对您在此处With
声明的常见误用 - 您只是因为您懒惰(没有违法行为)而使用它,并且不想在使用该对象的每一行前面键入rst.
。
正确使用会With
阻止本身保留引用,如下所示:
With GetRecordset 'a function that returns a recordset
.AddNew
!MyValue = 1
.Update
.Bookmark = .LastModified
.Close
End With
..不是说我建议使用这样的记录集,但是你明白了;)
答案 2 :(得分:3)
在这种情况下,编译器如何知道在With块的开头(而不是在其他点)恢复?它不会,虽然它可能是逻辑连接的(即,它在With
块内)仍然没有理由通过规则假设执行应该在该块的开始处重新开始,而没有明确引用恢复那个点。
你所要求的基本上是假设错误的来源,然后期望VBA内置这个假设,但它肯定不适用于所有甚至大多数情况,请考虑下面的假设{{1} }是打开/ etc。,实际错误在rst
属性引发,你的错误处理程序没有考虑到这一点,因此在块的开头重新启动将导致无限的失败循环!
Bookmark
请参阅On Error GoTo ErrHand
With rst
.AddNew
!MyValue = 1
.Update
.Bookmark = "George Washington"
End With
声明中的文档:
https://msdn.microsoft.com/en-us/library/office/gg251630.aspx
您可以选择Resume
如果错误发生在与错误处理程序相同的过程中,则执行将继续执行导致错误的语句。如果在调用的过程中发生错误,则执行将在最后调用包含错误处理例程的过程的语句处继续执行。
或Resume
:
如果错误发生在与错误处理程序相同的过程中,则执行将继续执行,该语句紧跟在导致错误的语句之后。如果在被调用的过程中发生错误,则执行将继续执行,该语句紧跟在上一次调用包含错误处理例程(或On Error Resume Next语句)的过程之后的语句之后。
或Resume Next
执行将在所需行参数中指定的行处继续执行。 line参数是行标签或行号,并且必须与错误处理程序位于相同的过程中。