Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel VBA锁通过DAO访问数据库记录进行编辑_Excel_Ms Access_Vba_Dao - Fatal编程技术网

Excel VBA锁通过DAO访问数据库记录进行编辑

Excel VBA锁通过DAO访问数据库记录进行编辑,excel,ms-access,vba,dao,Excel,Ms Access,Vba,Dao,我开发了一个Excel应用程序,现在希望将所有数据存储在Access文件(而不是Excel工作表)中。我能够读入和写出数据,我的问题与处理并发用户有关。大约有150-200个方形图像,单击这些图像可以打开一个加载了数据的用户表单。用户可以进入并编辑任何数据,因此我希望确保两个用户不会同时编辑一条记录。考虑到它的大小,我不想锁定整个文件,只锁定一条记录。到目前为止,我读到的所有内容都表明记录仅在.Edit中锁定,但是我希望在用户打开UserForm后立即锁定它,然后应用他们所做的任何编辑并解锁它

我开发了一个Excel应用程序,现在希望将所有数据存储在Access文件(而不是Excel工作表)中。我能够读入和写出数据,我的问题与处理并发用户有关。大约有150-200个方形图像,单击这些图像可以打开一个加载了数据的用户表单。用户可以进入并编辑任何数据,因此我希望确保两个用户不会同时编辑一条记录。考虑到它的大小,我不想锁定整个文件,只锁定一条记录。到目前为止,我读到的所有内容都表明记录仅在.Edit中锁定,但是我希望在用户打开UserForm后立即锁定它,然后应用他们所做的任何编辑并解锁它

下面是我现在的代码,前三部分是主要关注点:

Sub OpenDAO()
   Set Db = DBEngine.Workspaces(0).OpenDatabase(Path, ReadOnly:=False)
   strSQL = "SELECT * FROM AccessDB1 WHERE ID = 5" '& Cells(1, Rng.Column)
   Set Rs = Db.OpenRecordset(strSQL)
End Sub
'==========================================================================
Sub CloseDAO()
On Error Resume Next
   Rs.Close
   Set dbC = Nothing
   Set Rs = Nothing
   Set Db = Nothing
End Sub
'==========================================================================
Function ADO_update(Target As Range)
   Set ws = Sheets("Sheet1")
   Set dbC = DBEngine.Workspaces(0).Databases(0)

   'if no change exit function
   If Target.Value = oldValue Then GoTo 0

On Error GoTo trans_Err
    'begin the transaction
    DBEngine.BeginTrans
    dbC.Execute "UPDATE AccessDB1 SET Field1 = 5 WHERE ID= 5"
    DBEngine.CommitTrans dbForceOSFlush
Exit Function

trans_Err:
   'roll back the transaction
   Workspaces(0).Rollback
0
End Function
'==========================================================================
Function MakeSQLText(data As Variant)
   If (IsNumeric(data)) Then
       MakeSQLText = data
   Else
       MakeSQLText = "'" & Replace(data, "'", "''") & "'"
   End If
End Function

按设计,对于每个Microsoft的DAO,行级锁定不可用。不过,本文确实描述了如何将ADO与DAO结合使用来实现这一点。就我个人而言,我会向表中添加一个布尔值,其中包含默认为False的数据。然后,我会在显示表单之前检查该字段是否为False,如果为True,则记录中有其他人,并显示消息框或其他内容。如果为False,请打开表单并将记录更改为True。当它关闭时,将其设置回False。@GavinP我也想到了这一点,但如果Excel崩溃或布尔值没有更新回来,它可能会产生问题。至少它会添加维护来解锁记录(某种时间戳,只允许记录锁定一定时间),我似乎无法使用ADO锁定行,布尔选项是一个好主意,除了Excel崩溃之外。我认为最好的方法可能是在字段中写入日期/时间,然后在更新后将其设置回null。然后,当用户尝试编辑字段时,我将检查日期/时间是否在过去15分钟内(编辑模式的默认超时),如果是,则返回一条消息,说明当前正在编辑该字段。你们认为这种方法有什么缺点吗?@Phillip Nope。我可以使用我提供的链接中的方法,但只适用于MDB文件(这不是特别有用)。我也无法让它与ADO一起工作,现在也没有时间再处理它了。如果我有机会找到答案,我会回答的。打开表单时,您可以将记录集保持在.Edit模式,但这会为我锁定整个表,而不仅仅是相关行。可能是将其设置为仅锁定相关记录的一种方法,但我无法理解。根据设计,DAO per Microsoft不提供行级锁定。不过,本文确实描述了如何将ADO与DAO结合使用来实现这一点。就我个人而言,我会向表中添加一个布尔值,其中包含默认为False的数据。然后,我会在显示表单之前检查该字段是否为False,如果为True,则记录中有其他人,并显示消息框或其他内容。如果为False,请打开表单并将记录更改为True。当它关闭时,将其设置回False。@GavinP我也想到了这一点,但如果Excel崩溃或布尔值没有更新回来,它可能会产生问题。至少它会添加维护来解锁记录(某种时间戳,只允许记录锁定一定时间),我似乎无法使用ADO锁定行,布尔选项是一个好主意,除了Excel崩溃之外。我认为最好的方法可能是在字段中写入日期/时间,然后在更新后将其设置回null。然后,当用户尝试编辑字段时,我将检查日期/时间是否在过去15分钟内(编辑模式的默认超时),如果是,则返回一条消息,说明当前正在编辑该字段。你们认为这种方法有什么缺点吗?@Phillip Nope。我可以使用我提供的链接中的方法,但只适用于MDB文件(这不是特别有用)。我也无法让它与ADO一起工作,现在也没有时间再处理它了。如果我有机会找到答案,我会回答的。打开表单时,您可以将记录集保持在.Edit模式,但这会为我锁定整个表,而不仅仅是相关行。也许可以将其设置为只锁定相关记录,但我无法理解。