上下文
我在excel VBA中有一个应用程序,用于在远程数据库上进行只读查询。
查询是从UDF执行的。我的应用程序将记录集对象中的数据数组传递给函数,然后调用Excel将数组写入单元格范围的快速过程。
挑战
该应用程序必须能够选择返回数据集顶部的字段名称。这给我带来了巨大的性能挑战。我知道在VBA中添加或添加到2D数组的唯一方法是遍历整个数组。通常,通过将recordset.getRows()
对象直接传递到UDF可以避免这样的循环。但是,将字段列表和查询结果与循环方法(我所知道的唯一方法)结合使用时,我将可计算时间的查询时间加倍或增加两倍。
我以此为基准:对于2k行和5个字段的查询,不包括字段名称的平均计算时间为4.3秒,而使用字段名称的平均计算时间为9.8秒
我的第一次尝试是使用select语句中的UNION
子句将服务器上的字段名和记录集组合在一起(我的服务器是MySQL)。但是,这不起作用,因为UNION强制数据类型相等,将我的数字数据隐式转换为字符串。为了将它们转换回去,我必须遍历整个数组,而忽略了所获得的任何效率。
我的问题
是否可以调用记录集对象或VBA数组的任何对象方法,以在大数组前面添加一行而不会遍历整个大数组?在执行MySQL查询之前,所有字段名称都是已知的。
下面是我加入数组的循环。定义一个长度为记录集+ 1的新数组arr
,然后遍历它,首先添加字段,然后添加记录集数组的每一行:
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
最佳答案
使用Application.Index
可能是组合数组的最慢方法:改为使用常规的嵌套循环,您甚至都不会注意到任何命中-
Sub TT()
Dim a(1 To 2000, 1 To 10)
Dim b(1 To 2000, 1 To 10)
Dim cc(1 To 2000)
Dim r, c, t
t = Timer
For r = 1 To 2000
For c = 1 To 10
b(r, c) = a(r, c)
Next c
Next r
Debug.Print "Loop", Timer - t '>> 0.015625 sec
t = Timer
For r = 1 To 2000
cc(r) = Application.Index(a, r, 0)
Next r
Debug.Print "Index", Timer - t '>> 4.195313 sec
End Sub
关于mysql - Excel VBA:记录集的加入和性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31216613/