我想知道错误处理。如果在代码执行期间发生错误,并且我打开了记录集,我应该关闭它吗?尝试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
谢谢!
答案 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)有些人声称,在某些未识别的错误情况下,某些没有剩余引用的本地对象不能自动正确关闭。我从来没有见过这个。我从来没有见过记录。我从来没有读过一个实际的具体例子。但是,嘿,有些人提出这样的说法:或许这是真的。