У меня есть три UDF:
Private Function IsInArray(stringToBeFound As Variant, arr As Variant) As Boolean
IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0))
End Function
Эта функция проверяет, есть ли что-то в массиве.
Private Function data_to_array(data As Range)
Dim arrArray As Variant
Dim cell As Range
Dim z As Integer
z = 0
ReDim arrArray(1 To data.Cells.Count)
For Each cell In data
z = z + 1
arrArray(z) = cell.Value
Next cell
data_to_array = arrArray
End Function
Эта функция извлекает выбранные значения диапазона и помещает их в массив.
Private Function plot_vals(data As Variant, custom_arr As Variant)
Dim arrPlot As Variant
ReDim arrPlot(1 To UBound(data)) As Variant
Dim c As Integer
Dim cl As Integer
cl = 0
For c = 1 To UBound(data)
cl = cl + 1
If IsInArray(cl, custom_arr) Then
arrPlot(cl) = data(cl)
Else
arrPlot(cl) = CVErr(xlErrNA)
End If
Next c
plot_vals = arrPlot
End Function
Последний UDF выполняет цикл по массиву данных из второго UDF, и если индекс / позиция значения в data_array находится в custom_array, то возвращается его значение. В противном случае он помещает ошибку в массив.
Данные выглядят так:
Эти функции используются в Excel следующим образом:
data_to_array(A1:A5)
- этот UDF создает массив (от 1 до 5) со значениями из ячеек A1: A5.
plot_vals(data_to_array(A1:A5), {1,5})
- этот UDF создает массив (от 1 до 5) и использует второй аргумент для получения первого и пятые значения при внесении ошибок в другие индексы. Результатом является массив, например: {5,error,error,error,1}
Если бы я использовал функцию для данных выше, например: plot_vals(data_to_array(A1:A5), {1,2})
, то результатом был бы массив {5,4,error,error,error}
Этот UDF plot_val используется в именованном диапазоне, и этот именованный диапазон используется для отображения значений на диаграмме. Данные хранятся в именованном диапазоне myData, а функция во втором именованном диапазоне используется следующим образом: plot_vals(myData,{1,5})
.
Все работает, я могу отобразить это на диаграмме, все хорошо, но когда именованные диапазоны используются на диаграммах, каждый раз, когда я что-то меняю в своей книге, все функции пересчитываются, как ... 10 раз каждая вместо один раз . Это заставляет Excel замедляться / зависать, если эти функции используются много раз. Я попытался найти информацию о волатильности функций и о том, как ее отключить (по умолчанию она должна быть отключена?), Но, похоже, ничего не работает, и я не знаю, как это предотвратить. Я попытался воссоздать это в Excel, используя стандартные функции Excel в именованных диапазонах, но не могу найти правильную функцию, которая бы делала то, что хочу. UDF - это именно то, что мне нужно.
Когда эти именованные диапазоны НЕ используются в диаграммах, тогда ничего не происходит, но как только я использую именованный диапазон на диаграмме, он пересчитывает все даже при незначительном изменении рабочая тетрадь . Незначительное изменение значения - копирование / вставка / добавление строк и т. Д. c.
Как я могу этого избежать? Как пересчитать UDF только один раз?
ИЗМЕНИТЬ при дальнейших исследованиях :
Я пробовал потенциальные решения, предоставленные Чарльзом Вильямсом: https://fastexcel.wordpress.com/2011/11/25/writing-efficient-vba-udfs-part-7-udfs-calculated-multiple-times/
Его потенциальные решения ничего не меняют.
Я также пробовал использовать событие Sheet_Change, меняя вычисления на ручные, а затем обратно на автоматические c. Это помогает, но очищает буфер обмена (неприемлемо) и вызывает проблемы с другими моими макросами, поэтому это решение "no- go".
Также стоит отметить, что как только диаграмма удаляется, а UDF остаются в именованных диапазонах, все работает нормально и гладко. Но когда эти именованные диапазоны находятся в формулах серии диаграмм, все пересчитывается 100 раз.