trying use memory make

Forum home » Delegate support and help forum » Microsoft Access VBA Training and help » Trying to use memory to make processing quicker | Access forum

Trying to use memory to make processing quicker | Access forum

resolvedResolved · Low Priority · Version 2007

Lee has attended:
Access VBA course

Trying to use memory to make processing quicker

Hi Anthony

I am trying to use your suggestion of using Arrays to do calculations in memory rather than using recordsets.

For example I have an Array with 2 fields. The first field is Part Number and the second field is a Number (eg Qty). I have another table of part numbers and quantities and I want to add the 2 quantities together into the first Array. So I have also copied the data from the second table into a second Array.
How do I now get the Arrays to reference each other correctly without having to nest 2 loops. There are about 30,000 records in the second Array and 300,000 records in the first. Nesting 2 loops takes for ever.
If I do this as a normal query with the part numbers linked it takes only a few seconds, but looping round each record in the code (even with Exit For once it has found a match) takes almost 7 minutes.
Is there some way to run SQL on the 2 Arrays or something else to make the process much quicker?

Option Compare Database
Option Explicit
Public DataArray() As Variant
Public DataArray2() As Variant

Sub testgrossfcst()

Dim dbData As DAO.Database
Set dbData = CurrentDb

Dim strSQL As String
Dim LngCount As Long, LngCount2 As Long

' Get table XREFERENCE_PREPROD into recordset rstXREF_PRE
' This table has over 300,000 records
strSQL = "SELECT * FROM XREFERENCE_PREPROD"
Dim rstXREF_PRE As DAO.Recordset
Set rstXREF_PRE = dbData.OpenRecordset(strSQL)
rstXREF_PRE.MoveLast
rstXREF_PRE.MoveFirst

'Create Array with number of records to match rstXREF_PRE
ReDim DataArray(1 To rstXREF_PRE.RecordCount, 1 To 2) As Variant

'Add each record from XREF_PRE into the Array
For LngCount = 1 To rstXREF_PRE.RecordCount
DataArray(LngCount, 1) = rstXREF_PRE.Fields("CP_REF_X")
DataArray(LngCount, 2) = 0
rstXREF_PRE.MoveNext
Next LngCount

'Clear out the recordset no longer needed
Set rstXREF_PRE = Nothing

'Get table aeoq_drp orders into recordset rstAEOQ_DRP
'this table has over 30,000 records
strSQL = "SELECT * FROM [aeoq drp]"
Dim rstAEOQ_DRP As DAO.Recordset
Set rstAEOQ_DRP = dbData.OpenRecordset(strSQL)
rstAEOQ_DRP.MoveLast
rstAEOQ_DRP.MoveFirst

'Create Array ready for taking contents of recordset
ReDim DataArray2(1 To rstAEOQ_DRP.RecordCount, 1 To 2) As Variant

'Copy contents of recordset into Array2
For LngCount = 1 To rstAEOQ_DRP.RecordCount
DataArray2(LngCount, 1) = rstAEOQ_DRP.Fields("SOURCE_REF_O")
DataArray2(LngCount, 2) = rstAEOQ_DRP.Fields("SumOfGOOD_QTY_O")
rstAEOQ_DRP.MoveNext
Next LngCount

'Update Array by adding the bom qty from Array2 to the existing value
'THIS IS THE SECTION WHICH TAKES AGES!!!
Dim starttime As Date
starttime = Time()

For LngCount2 = 1 To UBound(DataArray2, 1)
For LngCount = 1 To UBound(DataArray, 1)
If DataArray(LngCount, 1) = DataArray2(LngCount2, 1) Then
DataArray(LngCount, 2) = DataArray(LngCount, 2) + DataArray2(LngCount2, 1)
Exit For
End If
Next LngCount
Next LngCount2
Dim stoptime As Date
stoptime = Time()

'Clear out the recordset no longer needed
Set rstAEOQ_DRP = Nothing

Stop

End Sub

RE: Trying to use memory to make processing quicker

Hi Lee, you're not the only one to encounter this problem:

http://www.experts-exchange.com/Software/Office_Productivity/Office_Suites/MS_Office/Excel/Q_24176311.html

There are at least five ways I've see of getting recordsets into arrays for manipulation all of which have different end speeds and the only way for me to give you proper feedback on this would be to play with the data and try out different methods. However...

First, I would use GetRows (http://bytes.com/topic/access/insights/789969-retrieving-data-dao-recordset-using-getrows) to get the recordset into the array. However, I would probably try conditionally populating one array based on a calculations directly from the recordset, rather than getting the two arrays into memory first. I would also keep an eye on what the processor is doing when the second array is being created. Is it at 100%? And of course, if it only takes a couple of seconds with the initial SQL query I'd absolutely stick with that. Try either using just arrays, or just DAO or just SQL if you can.

Hope this helps,

Anthony

RE: Trying to use memory to make processing quicker

Thanks Anthony. But the issue isn't getting the data into Arrays. I have got the data in 2 arrays and that was quick. Now I want to combine the data. So the data is already in 2 arrays in memory and now I want to update one field in Array1 by adding data from Array 2, where the first filed of Array 1 equals the first field in Array 2. But because the 2 Arrays are arrays I can't use SQL. How else can I JOIN the Arrays. I have used the following but it is very slow. What else can I do to combine the data. This is just a test to find out how to do this. If I can find a quick way to do this JOIN then I will use it for more complicated operations.

Thanks.


'Update Array by adding the bom qty from Array2 to the existing value
'THIS IS THE SECTION WHICH TAKES AGES!!!
For LngCount2 = 1 To UBound(DataArray2, 1)
For LngCount = 1 To UBound(DataArray, 1)
If DataArray(LngCount, 1) = DataArray2(LngCount2, 1) Then
DataArray(LngCount, 2) = DataArray(LngCount, 2) + DataArray2(LngCount2, 1)
Exit For
End If
Next LngCount
Next LngCount2

 

Training courses

 

Training information:

Welcome. Please choose your application (eg. Excel) and then post your question.

Our Microsoft Qualified trainers will then respond within 24 hours (working days).

Frequently Asked Questions
What does 'Resolved' mean?

Any suggestions, questions or comments? Please post in the Improve the forum thread.


 

Access tip:

Creating Parameter wildcard queries

To creat a parameter query that also uses a wildcard, in the query design type in like []+*.

View all Access hints and tips


Server loaded in 0.05 secs.