The Context
I have an app in excel VBA for making read-only queries on a remote database.
Queries are executed from UDF's. My app passes an array of data from the recordset object to the function and Excel's fast process for writing an array to a cell range is invoked.
The Challenge
The app must be able to optionally return field names at the top of the dataset. This is presenting a huge performance challenge for me. The only way I know of to append or prepend to a 2D array in VBA is to loop through the entire array. Normally, I'm spared such a loop by passing the recordset.getRows() object directly to my UDF. However, when combining the list of fields and the result of the query with the looping method (the only method I'm aware of) I double or triple my calculation time for sizable queries.
I benchmarked this: for a query of 2k rows and 5 fields, average calc time without field names included is 4.3 seconds, vs. 9.8 seconds with field names
My first try was to combine the field names and recordset on the server using a UNION clause in my select statement (my server is MySQL). This does not work, however, since UNION forces data-type equality, implicitly converting my numerical data to strings. To convert them back I'd have to loop through the array, negating any efficiency gained.
My Question
Is there any object method of the recordset object or of VBA arrays that could be called upon to prepend a row to a large array without looping through the entire large array? The field names are all known before the MySQL query is executed.
My loop for joining the arrays is below. Define a new array arr of length of the recordset + 1, then loop through it, first adding the fields, then each row of the recordset array:
For r = LBound(arr, 1) To UBound(arr, 1)
If r = LBound(arr, 1) Then
arr(r) = fieldArray
Else
arr(r) = Application.Index(rs_array, r - 1, 0)
End If
Next
V = Range(row_of_field_names)would produce an array of sizeV(1 to 1, 1 to num_of_field_names). This should be faster than looping through the entire array. - Ron Rosenfeld