带有“With”语句的VBA错误处理程序

时间:2015-02-25 17:22:41

标签: vba access-vba

如果没有设置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条),但我很好奇这是否可行。

3 个答案:

答案 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参数是行标签或行号,并且必须与错误处理程序位于相同的过程中。