UDF加速

时间:2018-08-27 10:30:35

标签: vba excel-vba user-defined-functions acceleration

有一个Udf效果很好,但是很慢。 我知道如何加速Sub:

Application.ScreenUpdating = False

Application.Calculation = xlCalculationManual

Application.EnableEvents = False

这适合Function吗? 如果没有,我如何加快Udf的速度?

Function Fav(Diapozon As Range) As Long
    Application.Volatile

    Dim n As Long

    For x = 1 To 4
        For y = 0 To 1
            If Diapozon.Value = Cells(31, 3).Value Then
                n = 0
                Exit For
            End If

            If Diapozon.Value = Cells(x + 29, y + 10).Value Or Diapozon.Offset(0, 1).Value = Cells(x + 29, y + 10).Value Then
                n = 1
            End If
         Next y
     Next x

     Fav = n
End Function

1 个答案:

答案 0 :(得分:1)

我同意有关丢失Application.Volatile的评论之一。但是,我将详细说明一些内容。

正如@JvdV所指出的,只要任何内容发生变化,使用Application.Volatile都会导致重新计算。这会大大减慢计算速度(和工作簿,因为打开了更多或更大的工作簿)。

但是,我也可以从您的Cells(..., ...).Value中看到,对于UDF当前的编程方式,如果没有使用Application.Volitile进行硬编码引用的值之一,它可能不会总是准确地更新细胞的变化。

一种替代方法是重新处理UDF,以将其检查的Diapozon范围包括为附加输入参数。通过将这些范围作为参数包含在实际的UDF中,它告诉Excel UDF取决于这些范围,并且只要其中一个更改,就应重新计算。

例如,在下面的UDF代码中,nextDiapozonDiapozon.Offset(0, 1)nonMatchRange("C31")等效于Cells(31, 3),而rngCompareRange("J30:K33")相当于您正在循环通过的单元格:

Function Fav(Diapozon As Range, nextDiapozon As Range, nonMatch As Range, rngCompare As Range,) As Long
    Dim n As Long 'Default start value = 0
    Dim cell_var as Variant

    If Diapozon.Value <> nonMatch.Value then
        For each cell_var in rngCompare
            If Diapozon.Value = cell_var.Value Or nextDiapozon.Value = cell_var.Value Then
                n = 1
            End If
        Next cell_var
    End If

    Fav = n
End Function