如何在Microsoft Access中加快批量“更新”

时间:2019-01-03 03:31:35

标签: excel vba ms-access dao

我正在使用VBA词典在Access中执行“ upsert”。我正在循环我的字典键,如果该键存在于Access表中,那么我将对其进行更新。如果没有,它将插入它。但是,我的表包含200k +行,这使代码的执行速度非常慢(例如,完成5分钟,甚至没有完成5%),因为迭代需要在整个表中搜索“ LOC”(我的键)。

我有办法大大加快此过程吗? 我的代码在下面,感谢您的帮助。

Sub UpdateDatabase(dict As Object)

Dim db As Database
Dim rs As DAO.Recordset

Set db = OpenDatabase("C:\XXX\myDB.accdb")
Set rs = db.OpenRecordset("MyTable", dbOpenDynaset)


For Each varKey In dict.Keys()

    'Table is searched for key
    rs.FindFirst "[LOCID] = '" & varKey & "'"
    If rs.NoMatch Then
        'If the key was not found, insert it
        rs.AddNew
        rs!LOCID = varKey
        rs![Status] = "To Start"
        rs.Update
    Else
        'If the key was found, update its status
        rs.Edit
        rs![Status] = "Done"
        rs.Update
    End If
Next

rs.Close
db.Close

Application.StatusBar = False
End Sub

编辑:

我在上面的代码中发现了瓶颈。这是一行:

rs.FindFirst "[LOCID] = '" & varKey & "'"

这用于查找密钥是否在数据库中。删除它(并简单地插入新数据)可以加快过程,并且只需几秒钟即可完成。有没有一种快速的方法来确定表中是否已经存在值?

2 个答案:

答案 0 :(得分:3)

首先: dict集合有多大。 (5、10或1000 ???)。

接下来,LOCID是该表“ MyTable”中的索引列。

如果LOCID已经是N索引列,则可以使用以下代码。它将使速度提高大约100倍或更多倍:

假定该表不是链接表,但实际上是数据库中的表。

请注意,您必须以“可操作的”方式打开有问题的表-这是默认设置,因此我删除了dbOpenDynaset)

此代码将解决问题:

Dim db        As DAO.Database
Dim rs        As DAO.Recordset


Set db = OpenDatabase("C:\XXX\myDB.accdb")
Set rs = db.OpenRecordset("MyTable")     ' <--- note this!!!

rs.Index = "LOCID"

For Each varKey In dict.Keys()

  'Table is searched for key
  rs.Seek "=", varKey
  If rs.NoMatch = True Then
      'If the key was not found, insert it
      rs.AddNew
      rs!LOCID = varKey
      rs![Status] = "To Start"
      rs.Update
  Else
      'If the key was found, update its status
      rs.Edit
      rs![Status] = "Done"
      rs.Update
  End If
Next

rs.Close
db.Close

您还需要确定LOCID列上实际索引的名称。我在上面使用了LOCID,但最好打开具有访问权限的数据库,将表翻转到设计模式,然后单击功能区“索引”按钮。如果LOCID是主键,则很有可能将索引命名为PrimaryKey。因此,您需要索引的名称。

答案 1 :(得分:0)

遵照他人的建议;从根本上不做循环。进行操作查询(追加或更新)。

这是“程序员”和“数据库开发人员”之间最常见的区别……