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