Для того, чтобы управлять пересчётом пользовательской функции, можно воспользоваться вышеприведённым советом и создать следующий "шаблон" (см. ниже). Подобный подход, позволит Вам создать функцию, которая будет пересчитываемой (volatile) по умолчанию, т.к. значение необязательного аргумента Пересчёт, который и отвечает за метод пересчёта этой функции, равно True. Когда же надобность в подобном способе пересчёта отпадёт, Вам достаточно будет передать эту аргументу значение ЛОЖЬ или 0.
code: #vba
Function Имя_функции(Аргумент1 As Тип, Аргумент2 As Тип, ..., Optional Пересчёт As Boolean = True) As Тип
Application.Volatile Пересчёт
'Здесь выполняются необходимые вычисления
Имя_функции = Результат вычислений
End Function
Далее следует пример пользовательской функции, созданной на основании предложенного шаблона, а также примеры её вызова:
Function NamesOfSheets(IndexWorkbook As Integer, Optional VolatileOn As Boolean = True) As String
Application.Volatile VolatileOn
If Workbooks.Count >= IndexWorkbook Then
Dim iSheet As Object
For Each iSheet In Workbooks(IndexWorkbook).Sheets
NamesOfSheets = NamesOfSheets & ";" & iSheet.Name
Next
NamesOfSheets = Mid(NamesOfSheets, 2)
Else
NamesOfSheets = "нет книги с указанным индексом"
End If
End Function
=NamesOfSheets(3)
=NamesOfSheets(3;1)
=NamesOfSheets(3;ИСТИНА)
=NamesOfSheets(3;A1)
Четыре примера вызова пересчитываемой функции. В последнем случае желательно, чтобы ячейка A1 содержала значение или формулу, возвращающую ИСТИНА или 1
=NamesOfSheets(3;0)
=NamesOfSheets(3;ЛОЖЬ)
=NamesOfSheets(3;A1)
Три примера вызова не пересчитываемой функции. В последнем случае нужно, чтобы ячейка A1 содержала значение или формулу, возвращающую ЛОЖЬ или 0 (допускается также ссылка на пустую ячейку)
=NamesOfSheets(2;ДЕНЬНЕД(ТДАТА();2)<6)
А этот пример демонстрирует как можно обойтись без дополнительной ячейки и дать "отдохнуть" UDF в выходные, т.е. в субботу и воскресенье.