在访问共享驱动器上的文件时,是否可以改进Access 2010 VBA代码以更快地运行?

时间:2014-02-24 15:27:15

标签: vba ms-access access-vba

我有一个存储在网络驱动器上的Access 2010数据库。它执行以下操作:

  1. 拉出250,000份的清单(这很好)
  2. 分析VBA中的部件号
  3. 将分析结果保存到2D数组
  4. 将列表写回数据库中的表以供其他数据库使用
  5. 如果我在保存到桌面的数据库中运行此过程,则需要大约50秒才能完成。

    如果我使用保存在网络驱动器上的数据库运行它,则需要大约300倍的时间。似乎花费时间最长的元素是从数组到表

    写入结果
    Sub WritePMROutput()
    Status "Writing output to tblPmrParts"
    Set db = CurrentDb
    Dim rstOutput As DAO.Recordset
    Set rstOutput = db.OpenRecordset("tblPMRParts")
    
    db.Execute "DELETE tblPMRParts.* FROM tblPMRParts;" 'clear the table of all data before wriing new data
    
    intPMR = 0
    Do Until intPMR = intArrPMRSze 'loop until the counter reaches the size of the array
    With rstOutput
        .AddNew 'new line in output table
        !PMRID = arrPMR(intPMR, 0)
        !strayChars = arrPMR(intPMR, 1)
        !partno = arrPMR(intPMR, 2)
        !extension = arrPMR(intPMR, 3)
        If Not arrPMR(intPMR, 4) = "" Then !PartPatternID = arrPMR(intPMR, 4) 'the if not function seems to be required here as was having issues with data type with "" in a number field
        If Not arrPMR(intPMR, 5) = "" Then !ExtPatternID = arrPMR(intPMR, 5)
        .Update
        intPMR = intPMR + 1
    End With
    Loop
    
    LogUpdate "PDM", "tblPMRParts"
    
    End Sub
    

    有人可以建议我如何提高此操作的效率吗?或者我只是受到网络速度的限制?

    有趣的是,我可以将数据库复制到我的桌面,运行它,压缩它,然后在大约5-10分钟内将其复制回网络。

    提前致谢!

    修改

    在Kim建议的修复工作非常成功后,我想我会用结果报告。 情况是: 在本地PC上,大约需要60秒才能运行;跨网络,大约需要15,000秒才能运行

    在实现一个简单的事务之后(从sub开始,在结束时提交): 在本地PC上,35秒(几乎快两倍);跨越网络500秒 - (快30倍!)

    我实现的唯一问题是所需的记录锁数量引发了错误,但是快速谷歌搜索产生了一行简单的代码来暂时增加记录锁的数量dAO.DBEngine.SetOption dbMaxLocksPerFile, 300000 希望这将有助于其他人!

2 个答案:

答案 0 :(得分:1)

我指的是这个来源,因为它解释得很好:
http://support.microsoft.com/kb/146908

此处也提供了示例语法:

Private Sub Form_Load ()
     Dim Starttime, Endtime
     Dim db As Database
     Dim t As RecordSet
     Dim i As Integer
     Dim tempName As String
     Dim temphone As String
     Set db = Workspace(0).OpenDatabase("c:\vb\BIBLIO.MDB") ' Uses a
      ' copy of BIBLIO.MDB.
     Set t = db.OpenRecordSet("Publishers", dbOpenTable)
     Starttime = Now
     'BeginTrans  ' Add this and CommitTrans (below) for greater speed.
     For i = 1 To 100
        tempName = "testname" & Str$(i) ' Make an arbitrary unique
                                        '  string.
        tempPhone = Str$(i)             ' Make arbitrary number.
        t.AddNew ' AddNew clears copy buffer to prepare for new record.
        t!PubID = 30 + i  ' Set primary key to unique value.
        t!Name = tempName  ' Set Name field to unique value.
        t!Telephone = tempPhone  ' Set Telephone field to unique value.
        t.Update   ' Write the record to disk or to transaction buffer.
     Next i
     'CommitTrans  ' Add this and BeginTrans (above) for greater speed.
     Endtime = Now
     MsgBox "Time required= " & Format(Endtime - Starttime, "hh:mm:ss")
     t.Close
     db.Close
     End
  End Sub

您可以使用数据库事务来减少对表的读写次数 您在内存中执行循环和逻辑,但只将记录集提交到数据库一次。

来自网站的引用:

  

如果您不使用BeginTrans和CommitTrans语句,请执行此操作   程序报告在486/66 PC上添加100条记录需要17秒。当你   添加BeginTrans和CommitTrans,如上面的程序注释所示,   该程序在同一台计算机上只需不到1秒钟。   性能可能因计算机而异。

答案 1 :(得分:-1)

Access的问题在于它是客户端数据库。每当Access针对表运行进程时,它必须将表的全部内容拉到本地空间,执行操作,然后将结果推回到数据库。这就是为什么大多数人最终选择使用SQL Server作为后端,因为它是服务器端,并且可以在服务器上进行处理(以存储过程和视图的形式),以最小化您带给前端的内容

删除表中记录的最有效方法是使用预先构造的DELETE查询。与使用db.Execute语句相反,您可以通过这样做来节省一点时间。但是,您也可以尝试将该语句更改为:

CurrentProject.Connection.Execute "DELETE * FROM tblPMRParts;",,,AdCmdText