从Excel设置VBA ADO连接到访问多个用户和文件的正确方法是什么?

我有几个用于input数据的excel文件。 文件在function上是相同的,对于我们的每个服务中心都是一样的。 在窗体中有button,启动一个macros,将数据转换为另一个表格上的表格格式,然后上传到Access数据库。

一切工作正常在我自己的电脑上。 添加新行,更新现有行并删除现有angular色。 我使用了早期的绑定,当我把文件移动到我们的networking驱动器时会导致问题。 我设法将文件转换为后期绑定,但随后出现其他问题。

大多数情况下,上传到Access不起作用,特别是当多个用户同时尝试做东西时。 最常见的错误代码是我没有使用可更新的查询,或者这种方法不支持向后滚动。 我很抱歉没有报告实际的错误代码,但目前我无法复制它们。

我的连接代码如下,是来自不同例子的复制粘贴代码的混合。

打开连接和其他prestuff

Sub excel2access() Const adUseClient = 3 Const adUseServer = 2 Const adLockOptimistic = 3 Const adOpenKeyset = 1 Const adOpenDynamic = 2 Dim oConn As Object Dim cmd As Object Dim rs As Object Dim r As Long Dim criteria As String Dim Rng As Range Set oConn = CreateObject("ADODB.Connection") Set cmd = CreateObject("ADODB.Command") oConn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _ "Data Source= '" & Range("dbpath").Value & "\" & Range("dbfile").Value & "' ;" Set rs = CreateObject("ADODB.Recordset") rs.CursorLocation = adUseClient rs.CursorType = adOpenStatic rs.LockType = adLockOptimistic rs.Open "Select * from need_rows WHERE service_center = '" & Range("scenter_name").Value & "'", oConn r = 2 ' the start row in the worksheet Sheets("data").Select 

这下面的位通过excel工作表中的数据来查找,并尝试从该服务中心find的logging集中find匹配。 如果未find匹配,则创build新logging,如果find匹配,则更新旧logging。

 Do While Len(Range("A" & r).Formula) > 0 With rs criteria = Range("D" & r).Value .Find "identifier='" & criteria & "'" If (.EOF = True) Or (.BOF = True) Then .AddNew ' create a new record .Fields("service_center") = Range("scenter_name").Value .Fields("product_id") = Range("A" & r).Value .Fields("quantity") = Range("B" & r).Value .Fields("use_date") = Range("C" & r).Value .Fields("identifier") = Range("D" & r).Value .Fields("file_type") = Range("file_type").Value .Fields("use_type") = Range("E" & r).Value .Fields("updated_at") = Now .Update Else If .Fields("quantity") <> Range("B" & r).Value Then .Fields("quantity") = Range("B" & r).Value .Fields("updated_at") = Now .Update ' stores the new record End If End If .MoveFirst End With r = r + 1 Loop rs.Close Set rs = Nothing Set oConn = Nothing MsgBox "Confirmation message" End Sub 

编辑:基于barrowc的链接,我将光标types更改为adOpenStatic。 我试了几个用户同时上传数据,一切正常。 直到有一个用户停留在这个文件中,花了很长时间在那里编辑数据,然后尝试上传数据到数据库,并得到以下错误信息: https : //dl.dropbox.com/u/3815482/vba_error.jpg

再次,我回到了从哪里开始。

另外,我也会公开反馈我的代码。

我正在使用Office 2010。

我做错了吗? 所有的帮助表示赞赏。

数据库被其他用户locking的时候会遇到很多问题。 这有几个原因:

  • 从我可以看到你没有处理错误。 因此,如果您的脚本错误一半的连接将被打开,从而导致locking问题。
  • 从外观上看,这些macros可能会使连接打开一段相当长的时间(假设没有错误)。

创build了很多连接到MS Access数据库的macros,我可以直接告诉你。 你将会遇到很多连接问题,数据库被某些电子表格所locking的数据库所locking,这些电子表格由于没有处理意外的错误(连接永远不会closures)等原因而一天到晚都处于打开状态。

即使一旦你解决了这个问题,你所需要的只是一个人使用电子表格与旧的代码,他们将继续locking数据库。

一个巨大的问题是,如果有人连接到数据库,而其他人已经打开数据库,我相信他们会inheritance已经打开的数据库的连接types,从而导致写入锁的菊花链。 然后您需要确保所有连接都被切断,以重置连接。

您还没有向我们展示数据是如何放置在电子表格中的。 也许你没有正确closures连接,这可能是数据库有时被locking的原因。

有很多不同的事情可以尝试解决这个问题:

  • 最简单的就是使用MS Access前端+ MS Access后端。
  • 而不是按下这个button,并通过连接string上传数据,你可以把它保存在一个文件夹,然后由坐在那里观看文件夹的MS访问数据库处理文件。 这将意味着你上传脚本将被写入MS Access,并只是正在处理文件。 不会像现在的方法那样瞬时,但是在这种情况下,所有写入连接都将来自相同的机器/用户。
  • 坚持目前的方法:最终你可能会达到一个稳定的状态,但这将是很多的挫折和努力,确定锁的原因可能并不总是很容易。 你至less可以看看谁在那个时候locking了文件,并从那里工作,但如前所述,他们可能不是锁的原因。 他们可能刚刚inheritance了锁的types。

就我个人而言,我喜欢使用MS Excel来显示用户的MS Access数据,但避免像瘟疫得到它更新MS Access。 但是,如果我这样做,我会通过使用oConn.Execute命令不打开logging集,比较和减缓推动,因为这将保持连接打开太久。

对不起,墙上的文字。 希望这个信息有帮助。

听起来像Jet对于你的环境来说不够可靠。 我经常使用SQL Server / Access Data Projects将来自多个电子表格的信息整合到一个数据库后端,当你添加了6个用户时,这个后端不会被禁止。

您也可以尝试使用操作查询。 首先我会尝试更新使用(您可能需要格式化现在的值)

 dim count as long oConn.Execute "UPDATE need_rows SET quantity = " & Range("B" & r).Value & ", updated_at = #" & Now & "# WHERE service_center = '" & Range("scenter_name").Value & "' AND identifier='" & Range("D" & r).Value & "' AND quantity <> " & Range("B" & r).Value", count 

如果count为零,则不更新行,所以要么没有行更新,要么数量没有改变。 无论哪种方式,我们可以尝试插入,这将在后一种情况下失败,但不会造成问题。

 if count = 0 then count = oConn.Execute "INSERT ...", count if count = 0 then ' quantity has not changed, so nothing to do else ' new record inserted end if else ' record updated end if