上下文

我在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/

10-12 16:28