数据库意外关闭时使用DAO句柄时出现问题

时间:2015-04-24 03:40:38

标签: vba access-vba ms-access-2010 dao

我正在使用DAO句柄(在下面的代码中表示)来提高我在共享网络上找到的Access数据库的速度和性能,并且速度很慢。以下代码由专家提供给我,以帮助数据库提高其速度和性能。如您所见,打开数据库时会打开句柄(OpenAllDatabases True),然后在关闭数据库时将其关闭(OpenAllDatabases False)。

当数据库意外关闭时,我的问题就到了。当发生这种情况时,我会被告知我不再能够进入数据库的编辑模式,因为它已经被另一个用户打开了。我想这就是这种情况,因为当数据库意外关闭时,'OpenAllDatabases'被设置为TRUE。当发生这种情况时,我被迫以独占方式打开数据库,只对代码执行deactive,关闭并重新打开数据库,然后重建代码。这对我来说风险很大,特别是因为有多个用户使用该工具。以下是我的代码:

在主表格上:

Form_Load()
  OpenAllDatabases True
End Sub

在命令按钮上关闭数据库:

Private Sub cmdCloseDatabase_Click()
  OpenAllDatabases False
End Sub

模块

Sub OpenAllDatabases(pfInit As Boolean)
    ' Open a handle to all databases and keep it open during the entire time the application runs.
    ' Params  : pfInit   TRUE to initialize (call when application starts)
    '                    FALSE to close (call when application ends)
    ' Source  : Total Visual SourceBook

    Dim x As Integer
    Dim strName As String
    Dim strMsg As String

    ' Maximum number of back end databases to link
    Const cintMaxDatabases As Integer = 2

    ' List of databases kept in a static array so we can close them later
    Static dbsOpen() As DAO.Database

    If pfInit Then
        ReDim dbsOpen(1 To cintMaxDatabases)
        For x = 1 To cintMaxDatabases
            ' Specify your back end databases
            Select Case x
                Case 1:
                    strname="S:\Apps\PRESTO\BE.accdb"
            End Select
            strMsg = ""

    On Error Resume Next
            Set dbsOpen(x) = OpenDatabase(strName)
            If Err.Number > 0 Then
                strMsg = "Trouble opening database: " & strName & vbCrLf & _
                         "Make sure the drive is available." & vbCrLf & _
                         "Error: " & Err.Description & " (" & Err.Number & ")"
            End If

    On Error GoTo 0
            If strMsg <> "" Then
                MsgBox strMsg
                Exit For
            End If
        Next x
    Else
    On Error Resume Next
        For x = 1 To cintMaxDatabases
            dbsOpen(x).Close
        Next x
    End If
End Sub

2 个答案:

答案 0 :(得分:2)

Sub OpenAllDatabases中,我发现这两行存在问题:

Const cintMaxDatabases As Integer = 2
' ...
For x = 1 To cintMaxDatabases
    Select Case x
        Case 1:
            strname="S:\Apps\PRESTO\BE.accdb"
    End Select

您要经历两次循环,但只设置一次数据库路径。如果您关注代码,则表示您与“S:\ Apps \ PRESTO \ BE.accdb”建立了两个连接。

修正此错误,以便您只进行一次连接,并查看问题是否消失。

答案 1 :(得分:1)

好的,谢谢你解决这个问题。

我使用类似的代码,它始终有效。我一直在将你的代码与我的代码进行比较,并试图思考差异可能是什么。

我想让你尝试的另一件事是改变这一行:

Set dbsOpen(x) = OpenDatabase(strName)

要:

Set dbsOpen(x) = OpenDatabase(strName, ReadOnly:=True)

在我的快速测试中,这仍然会提高应用程序的性能,您的表单仍然可以写入后端数据。

这样,OpenAllDatabases无法在后端数据库上获得写锁定。当你的前端意外关闭时,看看这是否解决了这个问题。