我在网上找到这个代码来查询Access并将数据输入到excel(2003)中,但它比它应该慢得多:
Sub DataPull(SQLQuery, CellPaste)
Dim Con As New ADODB.Connection
Dim RST As New ADODB.Recordset
Dim DBlocation As String, DBName As String
Dim ContractingQuery As String
If SQLQuery = "" Then
Else
DBName = Range("DBName")
If Right(DBName, 4) <> ".mdb" Then DBName = DBName + ".mdb"
DBlocation = ActiveWorkbook.Path
If Right(DBlocation, 1) <> "\" Then DBlocation = DBlocation + "\"
Con.ConnectionString = DBlocation + DBName
Con.Provider = "Microsoft.Jet.OLEDB.4.0"
Con.Open
Set RST = Con.Execute(SQLQuery)
Range(CellPaste).CopyFromRecordset RST
Con.Close
End If
End Sub
问题是此代码需要很长时间。如果我打开Access并在那里运行查询大约需要十分之一的时间。反正有加速吗?或者这可能需要这么长时间?我的所有查询都是简单的选择查询,只有简单的where语句和没有连接。即使是“select * from [test]”查询也需要更长的时间。
编辑:我应该指定“Range(CellPaste).CopyFromRecordset RST”这一行需要很长时间。
答案 0 :(得分:3)
我不是专家,但我运行几乎完全相同的代码并取得了良好的效果。一个区别是我使用Command
对象以及Connection
对象。你在哪里
Set RST = Con.Execute(SQLQuery)
我
Dim cmd As ADODB.Command
Set cmd.ActiveConnection = con
cmd.CommandText = SQLQuery
Set RST = cmd.Execute
我不知道是否或为什么会有所帮助,但也许会有所帮助? : - )
答案 1 :(得分:2)
我认为你没有比较喜欢。
在Access中,当您查看Query的数据视图时会发生什么:
在您的VBA代码中:
我认为最重要的一点是Access中的数据视图在您要求之前不会获取整个结果集,通常是导航到结果集中的最后一行。 ADO将始终获取结果集中的所有行。
第二个最重要的是将读取的行(假设完整的结果集)读入UI元素所花费的时间,并且事实上Excel没有针对作业进行优化。
打开,关闭和释放连接和记录集应该是微不足道的,但仍然是一个因素。
我认为你需要在流程的每个步骤上做一些时间来找到瓶颈。与Access比较时,请确保获得完整的结果集,例如检查返回的行数。
答案 2 :(得分:1)
我建议您明确地创建Recordset
而不是隐式使用。{1}}
Execute
方法。
显式创建时,您可以设置对性能有影响的CursorType和LockType属性。
从我看到的,你在Excel中加载数据,然后关闭记录集。您不需要更新,统计记录等......所以我的建议是用Recordset
创建CursorType = adOpenForwardOnly & LockType = adLockReadOnly
:
...
RST.Open SQLQuery, Con, adOpenForwardOnly, adLockReadOnly
Range(CellPaste).CopyFromRecordset RST
...
答案 3 :(得分:1)
由于您使用的是Access 2003,因此使用DAO,使用Jet引擎会更快。
请参阅http://www.erlandsendata.no/english/index.php?d=envbadacexportdao了解示例代码。
请注意,您绝不应使用“As New”关键字,因为这会导致意外结果。
答案 4 :(得分:1)
我使用了你的代码并在不到7秒的时间内完成了38列和63780行的表格 - 大概是我所期望的 - 并且几乎瞬间完成了较小的记录集。
这是您遇到的那种表现吗?如果是这样,它与我从Excel到MDB后端的ADO连接所期望的一致。
如果你看到的性能比这要低得多,那么必然会有一些影响事物的局部环境条件。
答案 5 :(得分:1)
很多公式可能会引用查询。尝试暂时打开宏中的手动计算,并在所有查询完成更新后将其关闭。
这应该加快一点,但仍然无法解决潜在的问题。
答案 6 :(得分:0)
如果您检索了大量记录,则可以解释为什么Range(CellPaste)
需要这么长时间。 (如果在Access中执行查询,则不会检索所有记录,但如果执行CopyFromRecordset,则需要所有记录。)
CopyFromRecordset有一个MaxRows参数:
Public Function CopyFromRecordset ( _
Data As Object, _
<OptionalAttribute> MaxRows As Object, _
<OptionalAttribute> MaxColumns As Object _
) As Integer
尝试将此值设置为较低值(如10左右)会改变性能。
答案 7 :(得分:0)
以下转变或改进如何:
答案 8 :(得分:0)
我不知道它是否有帮助,但我使用VBA和ADO连接到Excel电子表格。
它正在快速检索记录(<5秒),但突然间它非常缓慢(15秒检索一条记录)。这就是引导我发帖的原因。
我意识到我不小心打开了Excel文件(我一直在编辑它)。
一旦我关闭它,所有人都再次快速闪电。
答案 9 :(得分:0)
10次中的9次问题与您正在使用的光标类型/位置有关。
通过网络连接使用动态游标可能会减慢数据检索速度,即使查询执行速度非常快。
如果您想快速获取大量数据,则需要在连接上使用CursorLocation = adUseClient。这意味着你只有一个静态的本地光标,所以你不会从其他用户那里得到实时更新。
但是 - 如果您只是在阅读数据,那么您将保存ADO返回到每个单独记录的数据库以检查更改。
我最近更改了这个,因为我有一个简单的循环,填充列表项,每个循环大约需要0.3秒。不要慢,但即使是30秒的1000条记录!仅更改光标位置可让整个过程在1秒内完成。