Excel VBA ADODB Access数据库查找-减少查询时间
我编写了一些VBA代码,用于查询access数据库并将该代码拉入单元格。它可以工作,但速度非常慢,主要取决于我写它的方式,但我正在努力加快速度 第一个查询和第二个查询相同,只是第二个查询的偏移量为1个月 我怎样才能加快速度 第一个问题是,我似乎必须在每个循环中连接并关闭数据库。如果我尝试在同一个数据库连接中运行这两个查询,我会得到一个错误 第二个问题是,加入似乎相当缓慢Excel VBA ADODB Access数据库查找-减少查询时间,excel,database,vba,ms-access,adodb,Excel,Database,Vba,Ms Access,Adodb,我编写了一些VBA代码,用于查询access数据库并将该代码拉入单元格。它可以工作,但速度非常慢,主要取决于我写它的方式,但我正在努力加快速度 第一个查询和第二个查询相同,只是第二个查询的偏移量为1个月 我怎样才能加快速度 第一个问题是,我似乎必须在每个循环中连接并关闭数据库。如果我尝试在同一个数据库连接中运行这两个查询,我会得到一个错误 第二个问题是,加入似乎相当缓慢 ' FIRST MONTH QUERY db.Connect db.RunGetResults ("SELE
' FIRST MONTH QUERY
db.Connect
db.RunGetResults ("SELECT data.*, monthdata.VAL, monthdata.MONTHVAL, monthdata.GREEN, monthdata.RED, monthdata.RAG, monthdata.CREATOR FROM data LEFT JOIN monthdata ON data.UID = monthdata.DATAUID WHERE [UID] = '" & (IDcell) & "' AND [MONTHVAL] = #" & Format(Range("multidate"), "mm/dd/yyyy") & "#")
'Debug.Print db.Recordset.RecordCount
irow = IDcell.Row
Do Until db.Recordset.EOF
icol = 2
For Each ifield In db.Recordset.Fields
Sheet3.Cells(irow, icol) = ifield.Value
icol = icol + 1
Next
i = i + 1
progress i
db.Recordset.MoveNext
If db.Recordset.EOF = True Then
Else
End If
Loop
End If
Next
db.Disconnect
GoTo 69
' SECOND MONTH QUERY
For Each IDcell In Rng
If IDcell <> "" Then
db.Connect
'Application.Goto Reference:="month2"
db.RunGetResults ("SELECT monthdata.VAL, monthdata.MONTHVAL, monthdata.GREEN, monthdata.RED, monthdata.RAG, monthdata.CREATOR FROM data LEFT JOIN monthdata ON data.UID = monthdata.DATAUID WHERE [UID] = '" & (IDcell) & "' AND [MONTHVAL] = #" & Format((month2), "mm/dd/yyyy") & "#")
'Debug.Print db.Recordset.RecordCount
irow = IDcell.Row
Do Until db.Recordset.EOF
icol = 18
For Each ifield In db.Recordset.Fields
Sheet3.Cells(irow, icol) = ifield.Value
icol = icol + 1
Next
i = i + 1
progress i
db.Recordset.MoveNext
If db.Recordset.EOF = True Then
Else
End If
Loop
End If
Next
db.Disconnect
我建议只在需要时使用
adOpenKeyset、adLockOptimistic
锁定和锁定会产生开销。如果您只想阅读,请使用adOpenStatic、adlockdreadonly
。这不会锁定记录,并且在记录被删除时不需要连续连接来接收更新
我觉得你的整个数据库对象都很奇怪。您正在声明记录集和与事件的连接,但未侦听任何事件。这一切都会带来一点开销
您也可以断开记录集的连接,但如果您使用的是带有只读锁的静态类型记录集,则可能不会有太大区别。是将数据库集转储到某个范围的最快方法。如果问题出在查询性能上,那么首先要做的是确保表上有适当的索引。您可以将包含查询数据的db.Recordset传递给它,它将在不需要任何手动循环的情况下将其转储到工作表中。也不确定为什么要以读写模式打开连接,您没有更新数据库中的任何内容。还要注意:
GoTo 69
是一种罪恶,您和未来的开发人员将因使用它而受到惩罚。请参见“我似乎必须在每个循环中连接并关闭数据库”-您是否尝试过Db.Recordset.close
关闭记录集,然后再尝试重新使用它?另外,您是否使用了Debug.Print“WhatAmIDoing:”&Format(Now(),“hh:mm:ss”)
来跟踪哪些行占用了时间?
Public WithEvents Connection As ADODB.Connection
Public WithEvents Recordset As ADODB.Recordset
Public Command As New ADODB.Command
Public FilePath
Public Password
Public Function Connect()
If Connection.State = 1 Then Disconnect
AccessConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & FilePath & "';Jet OLEDB:Database Password='" & Password & "';"
Connection.ConnectionString = AccessConnect
Connection.CursorLocation = adUseClient
Connection.mode = adModeReadWrite
Connection.Open
End Function
Public Function Disconnect()
On Error Resume Next
Connection.Close
On Error GoTo 0
End Function
Public Function RunGetResults(qryString)
sqlQuery = qryString
Recordset.Open sqlQuery, Connection, adOpenKeyset, adLockOptimistic
End Function
Public Function Execute(qryString)
Connection.Execute (qryString)
End Function
Public Function Esc(eString)
eString = Replace(eString, "'", "''")
Esc = eString
End Function
Private Sub Class_Initialize()
Set Connection = New ADODB.Connection
Set Recordset = New ADODB.Recordset
Password = "xxxxx"
End Sub