Пользовательские функции НЕ пересчитываются
Недавно я взял большой, стабильный XLSM файл и разделил его на XLAM и XLSX. Тысячи ячеек в вызове XLSX (udfs) функционируют в XLAM, и каждый такой udf начинается с утверждения "Application.Volatile" (overkill, чтобы заставить recalc).
XLSX НЕ будет пересчитываться с F9 через Ctrl-Alt-Shift F9, а также с Cell.Calculate через Application.CalculateFull. Ячейки XLSX просто "мертвы"... но... Я могу разбудить их один за другим, если я нажму F2, чтобы отредактировать формулу, а затем нажмите ENTER. Ячейки, пробудившиеся таким образом, кажутся бодрствующими и обычно повторяются после этого.
Кто-нибудь сталкивался с этим странным поведением и есть ли какие-либо дополнительные способы заставить Excel восстановить граф с нуля, что я должен попробовать?
Еще одна заметка в случае, если это имеет значение: я открыл XLAM и XLSX через File Open и не установил XLAM с помощью File... Options... Addins route - потому что в прошлом, когда я это сделал, как только вы "снимите галочку" и установите XLAM, тогда все ссылки UDF заменяются ссылками на полный путь - довольно уродливые. В качестве альтернативы, если кто-то может обрисовать обходной путь для установки добавок XLAM, которые не создают неработающих ссылок во всем мире, я пойду с этим.
Ответы
Ответ 1
Подумал - не знаю, почему у Microsoft есть эта "функция":
Условие возникает, когда виртуальный XLSX, который использует функцию XLAM, открывается/создается до открытия XLAM. В этом случае никакая ошибка не приведет к тому, что формулы XLSX будут привязываться к этим функциям XLAM и выполнять их, если вы не войдете в каждую ячейку и не коснитесь строки формулы и не нажмете ENTER (или, как я обнаружил, сделать это массово с помощью глобальной замены - в моем случае все funcs начали wa "k" , поэтому глобальная замена "k" на "k" фиксировала ошибку). Проблема не возникает, если сначала открывается XLAM.
Ответ 2
Это работает:
Sub Force_Recalc()
Cells.Replace What:="=", Replacement:="=", LookAt:=xlPart, SearchOrder _
:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
End Sub
Ответ 3
Вы можете принудительно пересчитать в этой ситуации путем поиска и замены на =
, который находится в начале всех формул. Вы также можете сделать это в макрос и сопоставить его с комбинацией клавиш.
Отредактировано для добавления
См. макрос Greg Glynn в его ответе.
Ответ 4
Вот что я нашел. Я не тестировал его, но я считаю, что может быть обход.
Это прямая цитата:
"Excel зависит от анализа входных аргументов функции, чтобы определить, когда функция должна быть оценена путем пересчета".
из http://www.decisionmodels.com/calcsecretsj.htm
Вот то, что я собираюсь попробовать позже сегодня.
Я собираюсь генерировать конкретный адрес таблицы динамически в пределах моей функции.
Основываясь на том, почему мы здесь, я не должен получать обновление, если значение на вычисленном адресе изменится.
Включая всю таблицу в качестве параметра, даже без использования параметра, функция должна обновляться, если что-либо в таблице изменяется.
Таким образом, ваша функция попадает в дерево зависимостей независимо от того, действительно ли вы обрабатываете всю таблицу.
Ответ 5
Одно из возможных решений: установите режим расчета вручную, затем вернитесь к автоматическому
Application.Calculation = xlCalculationManual
Application.Calculation = xlCalculationAutomatic
Ответ 6
У меня была такая же проблема... Я нашел (в другом сообщении), что добавление Application.Volatile к коду функции заставляло его вычислять с помощью таблицы (f9)
Ответ 7
Мой снимок экрана:
![введите описание изображения здесь]()
У меня была та же проблема. Найти и заменить работы, но не очень приятно. Мое решение:
перейдите на вкладку Данные > Изменить ссылки > Нажмите "Открыть исходный код", чтобы решить эту проблему.
Ответ 8
Для UDF, которые могут получить доступ к экземпляру Application
, могут использовать:
Application.CalculateFull()
Источник MSDN здесь
Ответ 9
Нажмите CTRL + ALT + SHIFT + F9
Это может потребоваться больше, чем нужно, но он обновил мой UDF.
(Источник)
Ответ 10
Excel будет отслеживать диапазон, упомянутый в формуле для любых изменений, я столкнулся с этим сегодня, и я думал и понял это. Поэтому, чтобы исправить это, сделайте фиктивный аргумент в своей функции, который принимает диапазон, который вы хотите контролировать или создать фиктивную функцию. В моем случае я назвал его monitorRange, который ничего не возвращает
Function monitorRange(rng As Range)
End Function
и я упомянул об этом в моем примере формулы
=myfunction(a,b) & monitorRange(RANGE_TO_MONITOR)
Это сработало очень хорошо, и оно должно работать с любой другой функцией