Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.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 如何加快批量';向上插入';在Microsoft Access中_Excel_Vba_Ms Access_Dao - Fatal编程技术网

Excel 如何加快批量';向上插入';在Microsoft Access中

Excel 如何加快批量';向上插入';在Microsoft Access中,excel,vba,ms-access,dao,Excel,Vba,Ms Access,Dao,我正在使用VBA字典在Access中执行“upsert”。我正在循环我的字典键,如果该键存在于访问表中,那么我会更新它。如果没有,则将其插入。然而,我的表包含200k+行,这使得代码执行速度非常慢(例如,5分钟,甚至还没有完成5%),因为迭代需要在整个表中搜索“LOC”(我的键) 我有没有办法显著加快这一进程? 我的代码如下,任何帮助都将不胜感激 Sub UpdateDatabase(dict As Object) Dim db As Database Dim rs As DAO.Record

我正在使用VBA字典在Access中执行“upsert”。我正在循环我的字典键,如果该键存在于访问表中,那么我会更新它。如果没有,则将其插入。然而,我的表包含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 & "'"
这用于查找密钥是否在数据库中。删除此项(以及简单地插入新数据)可以加快处理速度,并且只需几秒钟即可完成。有没有一种快速方法可以确定表中是否已经存在值?

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

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

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

假设该表不是链接表,而是数据库中的一个表

请注意,您必须以“actable”的形式打开有问题的表——这是默认设置,因此我删除了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
Dim db作为DAO.Database
Dim rs作为DAO.Recordset
Set db=OpenDatabase(“C:\XXX\myDB.accdb”)
Set rs=db.OpenRecordset(“MyTable”)”首先:
dict集合有多大。(5、10或1000??)

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

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

假设该表不是链接表,而是数据库中的一个表

请注意,您必须以“actable”的形式打开有问题的表——这是默认设置,因此我删除了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
Dim db作为DAO.Database
Dim rs作为DAO.Recordset
Set db=OpenDatabase(“C:\XXX\myDB.accdb”)

Set rs=db.OpenRecordset(“MyTable”)”与其他人的建议相同;从根本上说,不要做循环。执行操作查询(追加或更新)


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

其他人的建议也是如此;从根本上说,不要做循环。执行操作查询(追加或更新)


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

您可以定期调用UpdateBatch,而不是在每次更改之后。。。您的字典中有多少条目?@TimWilliams我发现性能瓶颈实际上不是添加数据,而是在确定值是否已在表中的代码中。我已经编辑了我的问题。可能是重复的。请参阅描述连接表的查询的答案。@June7我相信我所针对的方法的差异足以保证提出一个新问题。我的目标是使用DAO提高性能。DAO循环的工作速度比查询慢得多。如果需要性能,请使用查询,否则,如果是教程示例或性能实验,请确保键列具有索引,并使用
Seek
方法而不是
FindFirst
您可以定期调用UpdateBatch,而不是在每次更改之后。。。您的字典中有多少条目?@TimWilliams我发现性能瓶颈实际上不是添加数据,而是在确定值是否已在表中的代码中。我已经编辑了我的问题。可能是重复的。请参阅描述连接表的查询的答案。@June7我相信我所针对的方法的差异足以保证提出一个新问题。我的目标是使用DAO提高性能。DAO循环的工作速度比查询慢得多。如果需要性能,请使用查询,否则,如果是教程示例或性能实验,请确保键列具有索引,并使用
Seek
方法,而不是
FindFirst
,我想我们都同意这一点。但是,包含键列表的对象正在传递给例程。不清楚该列表的来源,但所提供的数据不是表格格式,也不是我们知道的数据源。毫无疑问,如果该数据来自某个表源,则首选操作查询。var“dict”是一个对象,它甚至不知道该数据是否来自给定发布代码中的表。如果有办法获取一个对象集合,并将其转换为一个查询,那么我洗耳恭听。我想我们都同意。但是,包含键列表的对象正在传递给例程。不清楚该列表的来源,但所提供的数据不是表格格式,也不是我们知道的数据源。毫无疑问,如果该数据来自某个表源,则首选操作查询。var“dict”是一个对象,它甚至不知道该数据是否来自给定发布代码中的表。如果有一种方法可以获取一个对象集合,并将其转换为一个查询,那么我洗耳恭听。