I found this code online to query Access and input the data into excel (2003), but it is much slower than it should be:
Sub DataPull(SQLQuery, CellPaste)
Dim
What about the following turnarounds or improvements:
I would recommend you to create the Recordset
explicitly rather than implicitly using the
Execute
method.
When creating explicitly you can set its CursorType and LockType properties which have impact on performance.
From what I see, you're loading data in Excel, then closing the recordset. You don't need to update, count records, etc... So my advice would be to create a Recordset
with CursorType = adOpenForwardOnly & LockType = adLockReadOnly
:
...
RST.Open SQLQuery, Con, adOpenForwardOnly, adLockReadOnly
Range(CellPaste).CopyFromRecordset RST
...
Recordset Object (ADO)
I don't think you are comparing like-with-like.
In Access, when you view a Query's dataview what happens is:
In your VBA code:
I think the most significant point there is that the dataview in Access doesn't fetch the entire resultset until you ask it to, usually by navigating to the last row in the resultset. ADO will always fetch all rows in the resultset.
Second most significant would be the time taken to read the fetched rows (assuming a full resultset) into the UI element and the fact Excel's isn't optimized for the job.
Opening, closing and releasing connections and recordsets should be insignificant but are still a factor.
I think you need to do some timings on each step of the process to find the bottleneck. When comparing to Access, ensure you are getting a full resultset e.g. check the number of rows returned.
The problem 9 times out of 10 is to do with the Cursor Type/Location you are using.
Using dynamic cursors over network connections can slow down the retrieval of data, even if the query executed very fast.
IF you want to get large amounts of data very quickly, you'll need to use CursorLocation = adUseClient on your connection. This mean's you'll only have a static local cursor, so you won't get live updated from other users.
However - if you are only reading data, you'll save ADO going back to the DB for each individual record to check for changes.
I recently changed this as I had a simple loop, populating a list item, and each loop was taking around 0.3s. Not to slow, but even on 1,000 records thats 30 seconds! Changing only the cursor location let the entire process complete in under 1 second.