VBA DAO.Recordset 为 null 或在尝试关闭它时未设置 - 但我事先检查它是否为 null
VBA DAO.Recordset is null or not set when trying to close it - But I check if its null beforehand
在访问应用程序的 VBA 代码中,有一个函数可以将某些数据库字段转换为另一种格式。这发生在 2 个表中,在代码中,您可以通过 2 个循环告诉它们 appart,用于 BOM 和 ROUTING。这段代码性能很差,因为有时有 200000 多条记录通过它。为了加快它的速度,我向它添加了交易——它现在快了 3 倍。但是,在尝试关闭 ROUTING 记录集时,我收到一条错误消息 "object invalid or no longer set"。因此,在我尝试关闭它之前,我向它添加了 2 个检查,不是什么都不是,也不是空的。当使用调试器逐步执行时,它通过了两个检查,然后尝试关闭记录集,然后转到给出消息的 ErrorHandler。使此错误更加奇怪的是它在关闭第一个循环的 BOM 记录集时没有问题。
代码:
Public Sub SomeSub()
' set up variables
Dim BOM As DAO.Recordset
Dim ROUTING As DAO.Recordset
Dim Workspace As DAO.Workspace
Set Workspace = DBEngine.Workspaces(0)
' set up errorhandler
On Error GoTo ErrorHandler
' run some process on BOM
Set BOM = CurrentDb.OpenRecordset("some query;", dbOpenDynaset, dbSeeChanges, dbOptimistic)
Workspace.BeginTrans
If Not (BOM.BOF And BOM.EOF) Then
BOM.MoveFirst
Do While (Not BOM.EOF) And (Not BOM.BOF)
' Do some stuff with BOM here
BOM.MoveNext
Loop
End If
Workspace.CommitTrans
BOM.Close
Set BOM = Nothing
Set ROUTING = CurrentDb.OpenRecordset("some query;", dbOpenDynaset, dbSeeChanges, dbOptimistic)
Workspace.BeginTrans
If Not (ROUTING.BOF And ROUTING.EOF) Then
ROUTING.MoveFirst
Do While (Not ROUTING.EOF)
' Do some stuff with ROUTING here
ROUTING.MoveNext
Loop
End If
Workspace.CommitTrans
Workspace.Close
If Not ROUTING Is Nothing Then
If Not ROUTING Is Null Then
ROUTING.Close
End If
End If
GoTo SuccesHandler
ErrorHandler:
MsgBox "Ran into error. Info: " & Err.number & ": " & Err.DESCRIPTION & vbNewLine
Resume SuccesHandler
SuccesHandler:
End Sub
问题:
- 为什么会出现这个错误?
- null/nothing 检查的正确方法是什么? (显然我这样做的方式行不通?)
您需要在关闭 Workspace
之前关闭 Recordset
。
Workspace.CommitTrans
If Not ROUTING Is Nothing Then
ROUTING.Close
Set ROUTING= Nothing
End If
Workspace.Close
Set Workspace = Nothing
我会调整该块以匹配有效的块 - 并将工作区处理移出该块:
Set ROUTING = CurrentDb.OpenRecordset("some query;", dbOpenDynaset, dbSeeChanges, dbOptimistic)
Workspace.BeginTrans
If Not (ROUTING.BOF And ROUTING.EOF) Then
ROUTING.MoveFirst
Do While (Not ROUTING.EOF)
' Do some stuff with ROUTING here
ROUTING.MoveNext
Loop
End If
Workspace.CommitTrans
ROUTING.Close
Set ROUTING = Nothing
Set Workspace = Nothing
在访问应用程序的 VBA 代码中,有一个函数可以将某些数据库字段转换为另一种格式。这发生在 2 个表中,在代码中,您可以通过 2 个循环告诉它们 appart,用于 BOM 和 ROUTING。这段代码性能很差,因为有时有 200000 多条记录通过它。为了加快它的速度,我向它添加了交易——它现在快了 3 倍。但是,在尝试关闭 ROUTING 记录集时,我收到一条错误消息 "object invalid or no longer set"。因此,在我尝试关闭它之前,我向它添加了 2 个检查,不是什么都不是,也不是空的。当使用调试器逐步执行时,它通过了两个检查,然后尝试关闭记录集,然后转到给出消息的 ErrorHandler。使此错误更加奇怪的是它在关闭第一个循环的 BOM 记录集时没有问题。 代码:
Public Sub SomeSub()
' set up variables
Dim BOM As DAO.Recordset
Dim ROUTING As DAO.Recordset
Dim Workspace As DAO.Workspace
Set Workspace = DBEngine.Workspaces(0)
' set up errorhandler
On Error GoTo ErrorHandler
' run some process on BOM
Set BOM = CurrentDb.OpenRecordset("some query;", dbOpenDynaset, dbSeeChanges, dbOptimistic)
Workspace.BeginTrans
If Not (BOM.BOF And BOM.EOF) Then
BOM.MoveFirst
Do While (Not BOM.EOF) And (Not BOM.BOF)
' Do some stuff with BOM here
BOM.MoveNext
Loop
End If
Workspace.CommitTrans
BOM.Close
Set BOM = Nothing
Set ROUTING = CurrentDb.OpenRecordset("some query;", dbOpenDynaset, dbSeeChanges, dbOptimistic)
Workspace.BeginTrans
If Not (ROUTING.BOF And ROUTING.EOF) Then
ROUTING.MoveFirst
Do While (Not ROUTING.EOF)
' Do some stuff with ROUTING here
ROUTING.MoveNext
Loop
End If
Workspace.CommitTrans
Workspace.Close
If Not ROUTING Is Nothing Then
If Not ROUTING Is Null Then
ROUTING.Close
End If
End If
GoTo SuccesHandler
ErrorHandler:
MsgBox "Ran into error. Info: " & Err.number & ": " & Err.DESCRIPTION & vbNewLine
Resume SuccesHandler
SuccesHandler:
End Sub
问题: - 为什么会出现这个错误? - null/nothing 检查的正确方法是什么? (显然我这样做的方式行不通?)
您需要在关闭 Workspace
之前关闭 Recordset
。
Workspace.CommitTrans
If Not ROUTING Is Nothing Then
ROUTING.Close
Set ROUTING= Nothing
End If
Workspace.Close
Set Workspace = Nothing
我会调整该块以匹配有效的块 - 并将工作区处理移出该块:
Set ROUTING = CurrentDb.OpenRecordset("some query;", dbOpenDynaset, dbSeeChanges, dbOptimistic)
Workspace.BeginTrans
If Not (ROUTING.BOF And ROUTING.EOF) Then
ROUTING.MoveFirst
Do While (Not ROUTING.EOF)
' Do some stuff with ROUTING here
ROUTING.MoveNext
Loop
End If
Workspace.CommitTrans
ROUTING.Close
Set ROUTING = Nothing
Set Workspace = Nothing