Udf ускорение - PullRequest
       23

Udf ускорение

0 голосов
/ 27 августа 2018

Есть Udf, который работает хорошо, но медленно.Я знаю, как ускорить Sub:

Application.ScreenUpdating = False

Application.Calculation = xlCalculationManual

Application.EnableEvents = False

Подходит ли это для функции?Если нет, как я могу ускорить 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 голосов
/ 27 августа 2018

Я согласен с одним из комментариев о потере Application.Volatile.Тем не менее, я собираюсь уточнить немного больше, чем то, что вписалось бы в комментарий.

Как указывалось @ JvdV , использование Application.Volatile вызовет пересчет всякий раз, когда что-нибудь изменений.Это может существенно замедлить вычисления (и рабочие книги, так как открываются более или более крупные книги).

Однако из ваших Cells(..., ...).Value я также вижу, что с тем, как в настоящий момент запрограммирована UDF, это может невсегда точно обновлять без Application.Volitile, если изменяется одно из значений в ячейках, на которые ссылается жесткий код.

Один из альтернативных вариантов - переработка UDF для включения диапазонов, для которых проверяется Diapozon какдополнительные входные параметры.Включая эти диапазоны в качестве параметров в фактическую UDF, он сообщает Excel, что UDF зависит от этих диапазонов и должен пересчитываться при каждом изменении одного из них.

Например, в приведенном ниже коде UDF, nextDiapozon - этоDiapozon.Offset(0, 1), nonMatch равно Range("C31") эквивалентно Cells(31, 3), а rngCompare равно Range("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
...