2016-03-20 13 views
1

Мне было интересно об обработке ошибок. Если во время выполнения кода возникает ошибка, и у меня есть набор записей, я должен закрыть его? Попытка операции recordset.close может вызвать ошибку, и поскольку я внутри части кода обработки ошибок, это будет необработанная ошибка.Access close Recordset при обработке ошибок

Если я отправлю код обратно для продолжения на другом ярлыке, он может стать бесконечным циклом. Теперь добавим одно логическое значение, чтобы проверить, будет ли это в первый раз появляться ошибка, но мне действительно нужна вся эта суета? Будет ли соединение оставаться открытым, если код завершается, и я его не закрываю? Это вызовет проблемы позже?

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

Да, это хорошая практика, чтобы закрыть открытые записи и соединения. Существует множество причин, см .: 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 объект не ничего, прежде чем attampt к закрой его.

+0

Ну, это трудно, тогда ... Спасибо! – vacip

+0

Я все равно не помещал его прямо в обработчик ошибок, хотя ... Или ничего другого не может вызвать ошибку при закрытии набора записей, кроме того, что он не установлен? – vacip

+1

Спасибо. Извините, я немного занят. Я добавил дополнительные строки для кода и улучшен обработчик ошибок. Это довольно часто кусок кода, который я использую для общих целей. Конечно, вы можете изменить его, чтобы поймать и обработать конкретный номер ошибки. –

1

VBA имеет автоматическую сборку мусора. Если в компиляторе VBA что-то не получается, все объекты будут выпущены, когда они выйдут из области видимости. В вашем примере:

Dim rs As DAO.Recordset 

'do things 
Exit Sub 

'do things 
End Sub 

... rs выпускается на конце Sub и автоматически закрывается. (FWIW, вы можете это увидеть, изучив скомпилированный код).

Классический ASP не имеет такой области, и объекты никогда не выходили из сферы действия, и записи никогда не выпускались автоматически. По этой причине ВСЕ Microsoft VBA ПРИМЕРЫ ПОКАЗЫВАЮТ ЗАКРЫТЬ И ОТКРЫТЬ. Это нужно сделать для ASP Classic.

Есть две другие причины для этого явно закрыть и выпустить:

1) C/C++ программисты не имеют автоматическое управление памятью. Они были полны ужаса и отвращения к идее оставить объекты открытыми. Это стиль кодирования.

2) Некоторые люди утверждают, что в некотором неопределенном случае ошибки локальные объекты, не содержащие ссылок, не будут автоматически закрыты правильно. Я этого никогда не видел. Я никогда не видел, чтобы это было документировано. Я никогда не читал о конкретном конкретном примере. Но эй, некоторые люди делают это утверждение: возможно, это правда.

Смежные вопросы