【问题标题】:Excel VBA Ctrl-Shift-Enter array function very slow compared to writing long worksheet function与编写长工作表函数相比,Excel VBA Ctrl-Shift-Enter 数组函数非常慢
【发布时间】:2020-02-26 18:58:29
【问题描述】:

我写了一个函数NA_2_X(Range, Variant)来接受一个数组,将所有#NA转换成一个Variant,并返回新的数组:

{=NA_2_X(A1:A3000, 0)}

这比编写费力的工作表函数要慢得多:

{=IF(ISNA(A1:A3000), 0, A1:A3000)}

300 次调用 NA_2_X() 大约需要 10 秒,而 IF() 语句几乎是即时的。最终我想做一些更复杂的事情,不能使用if() 语句。

Function NA_2_X(ByVal rng As Range, ByVal X As Variant) As Variant
    Dim NoRows As Long, NoCols As Long
    Dim r As Long, c As Long
    Dim ret() As Variant

    NoRows = rng.Rows.Count
    NoCols = rng.Columns.Count

    ReDim ret(1 To NoRows, 1 To NoCols)

    For c = 1 To NoCols
        For r = 1 To NoRows
            If Application.IsNA(rng(r, c)) Then
                ret(r, c) = X
            Else
                ret(r, c) = rng(r, c)
            End If
        Next r
    Next c

    NA_2_X = ret
    Exit Function
End Function

循环本身看起来很快,只是循环中心的几行看起来很慢。如果我删除对IsNA() 的调用,它需要大约一半的时间,但仍然很慢。

【问题讨论】:

  • 不太清楚你的意思(我不是 VBA 专家)。我确实尝试过 Dim tmp as Variant, tmp=rng(r,c) 然后引用 tmp 。它帮助了一点,但不是很多。
  • Dim tmp() as Variant,然后是tmp = rng.Value。然后循环遍历 temp(使用 LBoundUBound 来确定边界,而不是 NoRowsNoCols。这会更快(虽然不能保证它会像普通函数一样快)。跨度>
  • 使用带有错误参数的SpecialCells怎么样(虽然不能区分NA和其他)。
  • tmp.rng.Value 有帮助,它将每次调用的时间从 32ms 减少到 15ms,但不幸的是它仍然太慢了。看来 Application.IsNA(tmp(r,c)) 很慢,不知道为什么。
  • arr = .Evaluate("IF(ISNA(" & Rng.Address & ")," & X & "," & Rng.Address & ")") 会给你一个值数组。我也不确定您到底想做什么,所以建议的行可能毫无意义

标签: arrays excel vba performance function


【解决方案1】:

除了 BigBen 的建议之外,将“Application.IsNA(rng(r,c))”替换为“IsError(tmp(r,c))”使例程变得又快又好。

【讨论】:

    猜你喜欢
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2010-09-20
    • 2012-06-14
    • 2015-10-05
    • 1970-01-01
    • 2015-03-29
    相关资源
    最近更新 更多