【问题标题】:Excel VBA - Execution Time Of Macro Slower After Each ExecutionExcel VBA - 每次执行后宏的执行时间变慢
【发布时间】:2020-08-11 20:08:52
【问题描述】:

我的代码如下:

  1. 刷新一个大约有 10000 行的查询。

  2. 根据一些标准将数据拆分为各种二维数组(我总共有十几个不同的二维数组)。

  3. 将每个二维数组粘贴到不同的工作表中。

当我第一次运行宏需要约 18 秒,第二次运行约 30 秒,第三次运行约 35 秒,第四次运行约 45 秒,依此类推。每次运行时查询的数据都完全相同(变化不会那么频繁,或者最多可以变化一两行)。

如果有一些我不知道的记忆问题,有人可以解释一下吗?我还尝试在将矩阵粘贴到工作表之后将矩阵设置为等于 Nothing,但这并没有改变每次运行时的减速。任何帮助将不胜感激。

附:代码很长,我觉得把它都贴在这里也没有用。它的工作原理或多或少如下:

Sub GetMatrix()
    Dim Matrix As Variant, IndexMatrix As Long, i As Long, NoRows As Long
    IndexMatrix = 0
    ReDim Matrix(IndexMatrix, 2)
    NoRows = Application.CountA(Range("A:A"))
    For i = 2 To NoRows
        If Cells(i, 1) = "Something" Then
            Matrix(IndexMatrix, 0) = "Something"
            Matrix(IndexMatrix, 1) = "Something"
            Matrix(IndexMatrix, 2) = "Something"
            IndexMatrix = IndexMatrix + 1
            ReDim Preserve Matrix(IndexMatrix, 2)
        End If
    Next
    GetMatrix = Matrix
End Sub

【问题讨论】:

  • 我不知道这里有什么问题。但在性能问题的情况下,我会首先摆脱缓慢的 ReDim Preserve(大数组并最终缩小或收集?)。为什么不将单元格读取到数组中?在每次迭代中从工作表中读取也非常慢。将整个范围读取到数组中,然后检查是否等于“某物”
  • 第一次运行大约 18 秒,这对我来说没问题。因此 Redim Preserve 或从工作表中读取单元格不是问题。我有一种感觉,我以某种方式用我正在创建的 2D 数组来归档内存。我不确定这一点。
  • 所以在 Locals Window 中检查一下,尤其是第二次迭代
  • GetMatrix 是一个必须返回变体的函数吗?否则,为什么是最后一行代码 (GetMatrix = Matrix)?
  • 是的,我的错,GetMatrix 是一个函数,而不是一个子

标签: excel vba


【解决方案1】:

请尝试下一个改编的功能:

Function GetMatrix() As Variant
    Dim sh As Worksheet, arr As Variant, Matrix As Variant
    Dim IndexMatrix As Long, i As Long, LastRow As Long

    Set sh = ActiveSheet
    LastRow = sh.Range("A" & Rows.count).End(xlUp).Row
    arr = sh.Range("A1:A" & LastRow).Value
    ReDim Matrix(2, UBound(arr)) 'to admit redim preserve (only on the last dimension) at the end
    For i = 2 To LastRow
        If arr(i, 1) = "Something" Then
            Matrix(0, IndexMatrix) = "Something"
            Matrix(1, IndexMatrix) = "Something"
            Matrix(2, IndexMatrix) = "Something"
            IndexMatrix = IndexMatrix + 1
        End If
    Next
    ReDim Preserve Matrix(2, IndexMatrix - 1)
    GetMatrix = Matrix
End Function

【讨论】:

  • 我会试试看,但为什么 ReDim Preserve 出现问题,因为第一次运行宏,只需要 18 秒?
  • @Lorenzo:当你处理少量数据时,它并不那么危险,但无论如何它对内存不好。 ReDim Preserve 将现有数组复制到具有更大内存分配的新位置。所以,它可能是一大堆开销。 Redim 只是创建新的更大的内存分配,而不从现有数组中复制数据,因此开销很小。这就是为什么一个好的做法是首先Redim 它以确保它可以容纳您需要加载的所有元素。并且只在最后使用Redim Preserve,使用迭代加载元素...
  • 按照建议更改了代码,但问题仍然存在:每次运行速度较慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-12
相关资源
最近更新 更多