Автоматическая переоценка энергонезависимой UDF

Скажем, у нас есть следующая энергонезависимая UDF:

Function Twice(ByRef x As Double) As Double
    Application.Volatile False
    Twice = 2 * x
End Function

который вводим в ячейку A1 со ссылкой на ячейку A2, т.е. в A1 ставим:

= Twice(A2)  

Кроме того, в A2 ставим случайную функцию, т.е. в A2 ставим:

=RAND()  

Теперь, если мы пересчитаем лист (скажем, нажав Shift + F9), значение в ячейке A2 изменится, но UDF не обновится, даже хотя его ссылка изменилась.

Как сделать, чтобы эта UDF обновлялась автоматически (т. е. без нажатия Ctrl+Alt+F9), когда ее опорное значение изменяется?


person Confounded    schedule 15.09.2015    source источник
comment
Удалите строкуApplication.Volatile False, как предложил @pnuts, и установите автоматический расчет рабочей книги вместо ручного.   -  person Siddharth Rout    schedule 15.09.2015
comment
@pnuts Не указывать явно Application.Volatile False — это то же самое, что указывать его, поскольку это настройка по умолчанию. Я просто поместил это здесь, чтобы быть явным в том, что я не хочу, чтобы функция была изменчивой.   -  person Confounded    schedule 15.09.2015
comment
Определите x как Variant.   -  person BrakNicku    schedule 15.09.2015
comment
Пожалуйста, не меняйте правку. В заголовке вашего вопроса не должно быть описания. Почтовая зона предназначена для этого.   -  person Siddharth Rout    schedule 15.09.2015
comment
@pnuts Я хочу, чтобы UDF менялся только тогда, когда изменяется значение в ячейке, на которую он ссылается (в примере ячейки A2). Я не хочу, чтобы он менялся, когда, скажем, изменяется значение в ячейке A3, что могло бы произойти, если бы функция была изменчивой.   -  person Confounded    schedule 15.09.2015
comment
@user3964075 user3964075 Кажется, это помогает. Спасибо. Не могли бы вы расширить свой комментарий до ответа, возможно, с некоторым объяснением того, почему это работает?   -  person Confounded    schedule 15.09.2015
comment
@SiddharthRout Уже есть несколько вопросов по пересчету UDF - хотел уточнить, что мой они не решаются. Кроме того, почему вы продолжаете писать с большой буквы почти каждое слово в заголовке?   -  person Confounded    schedule 15.09.2015
comment
Вот и все.. Я снял их с заглавных букв. :) Можно пояснить в самом посте. Область заголовка не предназначена для описательного текста.   -  person Siddharth Rout    schedule 15.09.2015
comment
@ Смущенный, извините, но я не могу дать вам подробное объяснение. Я думаю, это потому, что вам нужен параметр типа Range, чтобы он работал. Если вы передадите A2+1 в качестве параметра, он не будет пересчитываться. Может кто найдет более универсальное решение.   -  person BrakNicku    schedule 15.09.2015
comment
@pnuts Нет. В моем примере x зависит от A2. Когда значение (возвращаемое функцией) в A2 изменяется, я хочу, чтобы UDF переоценил. Если я сделаю UDF изменчивым, он будет пересчитываться при изменении любого значения в любой ячейке на листе.   -  person Confounded    schedule 15.09.2015
comment
@user3964075 user3964075 Хорошо, я проголосовал за ваш комментарий. Спасибо еще раз.   -  person Confounded    schedule 15.09.2015
comment
@ user3964075 Странно, определение параметров как Variant, похоже, превращает некоторые функции в Volatile. Нужно копнуть глубже.   -  person Confounded    schedule 15.09.2015


Ответы (1)


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

Если вы удалите утверждение Application.Volatile False, оно будет работать нормально.

См. https://fastexcel.wordpress.com/2011/09/05/false-volatility-is-this-a-bug/ для более подробного обсуждения этого и предположений относительно причины.

person Charles Williams    schedule 15.09.2015
comment
Спасибо за ваш ответ. Это решение (а также определение параметров как варианта) было предложено в комментариях к OP, но я приму ваш ответ, чтобы закрыть этот вопрос, и поскольку он предлагает дополнительные подробности и признает это «странное» поведение. - person Confounded; 15.09.2015