访问关闭错误处理中的Recordset

时间:2016-03-20 13:25:31

标签: vba ms-access error-handling access-vba

我想知道错误处理。如果在代码执行期间发生错误,并且我打开了记录集,我应该关闭它吗?尝试recordset.close操作可能会引发错误,因为我在错误处理代码部分内部,所以它将是一个未处理的错误。

如果我将代码发回以继续另一个标签,那么它可能会变成无限循环。现在添加一个布尔值来检查这是否是第一次出现错误会起作用,但是我真的需要这么大惊小怪吗? 如果代码终止并且我不关闭它,连接是否会保持打开状态?它会在以后引起麻烦吗?

Dim rs As DAO.Recordset

Set rs = CurrentDB.OpenRecordset("SELECT * FROM tblSetting")
On Error GoTo handler

    'do things

rs.Close
Set rs = Nothing

Exit Sub

handler:
 rs.Close
 'Set rs = Nothing '-this one is not necessary, as terminating the sub should clear up all references to it, hence Garbage Collector can pick it up
End Sub

这可行,但......真的吗?

...
Termination:
  rs.Close
  Set rs = Nothing
Exit Sub

handler:
 if ErrorHappened=True then
  msgbox "fatal error"
  exit sub
 else
  ErrorHappened=True
  resume termination
 End If

谢谢!

2 个答案:

答案 0 :(得分:2)

是的,关闭当前打开的记录集和连接是一种很好的做法。有很多原因,请参阅:Pooling in the Microsoft Data Access Components。这篇文章已经很老了,但主要的是保持......

我会用这种方式改进你的代码:

Exit_Subroutine:
    On Error Resume Next 'ignore errors to be able to execute each line
    If Not rst is Nothing Then rst.Close: Set rst = Nothing
    'do the same for the connection object!
    Exit Sub

ErrorHandler:
    MsgBox Err.Description, vbCritical, "Error" & Err.Number
    Resume Exit_Subroutine

您必须确保rst对象在您豁免关闭之前并非一无所获。

答案 1 :(得分:1)

VBA具有自动垃圾收集功能。除非VBA编译器内部出现问题,否则所有对象在超出范围时都会被释放。在您的示例中:

Dim rs As DAO.Recordset

'do things
Exit Sub

'do things
End Sub

... rs在End Sub发布,并自动关闭。 (FWIW,您可以通过检查已编译的代码来看到这一点)。

经典ASP没有这样的范围,对象永远不会超出范围,并且记录集永远不会自动释放。出于这个原因,所有Microsoft VBA示例显示显示关闭和释放。必须按照ASP Classic的方式进行。

明确关闭和释放还有另外两个原因:

1)C / C ++程序员没有自动内存管理。对于让物体打开的想法,他们充满了恐惧和厌恶。这是一种编码风格。

2)有些人声称,在某些未识别的错误情况下,某些没有剩余引用的本地对象不能自动正确关闭。我从来没有见过这个。我从来没有见过记录。我从来没有读过一个实际的具体例子。但是,嘿,有些人提出这样的说法:或许这是真的。