Пользовательские функции НЕ пересчитываются - PullRequest
16 голосов
/ 19 апреля 2011

Недавно я взял большой стабильный файл XLSM и разделил его на XLAM и XLSX. Тысячи ячеек в вызове XLSX (udfs) функционируют в XLAM, и каждый такой udf начинается с выражения «Application.Volatile» (избыточное значение, чтобы вызвать повторный вызов).

XLSX НЕ будет пересчитываться ни с F9 по Ctrl-Alt-Shift F9, ни с Cell.Calculate через Application.CalculateFull. Ячейки XLSX просто «мертвы» ... но ... я могу разбудить их одну за другой, если нажму F2, чтобы отредактировать формулу, а затем нажму ENTER. Клетки, пробуждаемые таким образом, похоже, бодрствуют и после этого нормально восстанавливаются.

Кто-нибудь сталкивался с таким странным поведением, и есть ли какие-либо дополнительные способы заставить Excel восстановить график calc с нуля, который я должен попробовать?

Еще одно примечание на случай, если это имеет значение: я открыл XLAM и XLSX через File Open, и не установил XLAM с помощью File ... Options ... Addins route - потому что в прошлом, когда я делал это в тот момент, когда вы "снимите галочку" и установите XLAM, все ссылки UDF будут заменены полными ссылками на пути - довольно уродливо. В качестве альтернативы, если кто-то может наметить обходной путь для установки надстроек XLAM, которые не создают неработающие ссылки везде, я пойду с этим.

Ответы [ 11 ]

8 голосов
/ 05 ноября 2015

Это работает:

Sub Force_Recalc()
    Cells.Replace What:="=", Replacement:="=", LookAt:=xlPart, SearchOrder _
        :=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
End Sub
6 голосов
/ 19 апреля 2011

Разобрался - не уверен, почему у Microsoft есть эта "особенность":

Условие возникает, когда первичный XLSX, использующий функцию XLAM, открывается / создается до открытия XLAM. В этом случае никакие уговоры не приведут к связыванию формул XLSX и выполнению этих функций XLAM, ЕСЛИ ВЫ не войдете в каждую ячейку и не коснетесь строки формул и не нажмете клавишу ВВОД (или, как я обнаружил, массово через глобальную замену). - в моем случае все funcs начинались с wa «k», поэтому глобальная замена «k» на «k» исправила ошибку). Проблема не возникает, если XLAM открывается первым.

4 голосов
/ 30 мая 2014

Вы можете принудительно пересчитать в этой ситуации путем поиска и замены на =, который находится в начале всех формул. Вы также можете превратить это в макрос и сопоставить его с комбинацией клавиш.

Отредактировано для добавления

Смотрите макрос, который есть у Грега Глинна в его ответе .

2 голосов
/ 21 декабря 2016

Для UDF с доступом к экземпляру Application можно использовать:

Application.CalculateFull()

Источник MSDN здесь

2 голосов
/ 16 марта 2016

Одно из возможных решений: установить режим расчета на ручной, а затем обратно на автоматический

    Application.Calculation = xlCalculationManual
    Application.Calculation = xlCalculationAutomatic
1 голос
/ 31 января 2017

Нажмите сочетание клавиш CTRL + ALT + SHIFT + F9

. Это может привести к повторному вызову больше, чем хотелось бы, но обновил мой UDF.

( Источник )

1 голос
/ 30 мая 2014

Вот что я нашел. Я не проверял это, но я думаю, что может быть обходной путь.

Это прямая цитата: «Excel зависит от анализа входных аргументов функции, чтобы определить, когда функция должна быть оценена путем пересчета».

от http://www.decisionmodels.com/calcsecretsj.htm

Вот что я собираюсь попробовать позже сегодня. Я собираюсь сгенерировать конкретный адрес таблицы, динамически в рамках моей функции. Исходя из того, почему мы здесь, я не должен получать обновление, если значение в вычисленном адресе меняется.

При включении всей таблицы в качестве параметра, даже без использования параметра, функция должна обновляться, если что-либо в таблице изменяется.

Таким образом, ваша функция обращается к дереву зависимостей независимо от того, обрабатываете ли вы всю таблицу.

0 голосов
/ 30 октября 2018

Лед по возрасту после первоначального вопроса, но столкнулся с подобной проблемой только сегодня, когда я создал UDF, чтобы определить, какие значения фильтра сводной таблицы были выбраны. UDF будет нормально работать при работе в редакторе макросов, а также при непосредственном обновлении поля, в котором использовалась UDF, но выдает «#VALUE!» при обновлении таблицы или сводной таблицы.

Это убивало меня до тех пор, пока я постепенно не добавил контент из моего оригинального UDF в простую функцию АлиА monitorRange. Затем я обнаружил, что в моей пользовательской функции есть оператор обновления сводной таблицы, который при удалении устраняет ошибку «#VALUE!». Ниже приведены конкретные оскорбительные строки из моей UDF, но общее правило заключается в том, что UDF не может иметь никакого кода в своей цепочке вызовов, который обновляет другое содержимое книги. То есть UDF должен только получать значения, НЕ устанавливать значения.

Я проверил это с помощью следующих двух сценариев, которые оба вызывают эту ошибку:

  1. Обновить сводку, например: pt.PivotCache.Refresh
  2. Изменить значение другой ячейки, например: Range("AA1").Value = "Test"

Странно, я проверил и обнаружил, что абсолютно нормально (на самом деле круто), что UDF может включать вызов MsgBox для отображения диалога без проблем. Это позволило бы UDF отслеживать диапазон, а затем открывать диалоговое окно msgbox для любого условия, которое вы хотите включить в UDF. Я буду помнить это для других ситуаций.

Надеюсь, это поможет другим, сталкивающимся с этой неприятной проблемой сора.

0 голосов
/ 24 мая 2017

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

Function monitorRange(rng As Range)
End Function

, и я упомянул об этом в моем примере формулы

=myfunction(a,b) & monitorRange(RANGE_TO_MONITOR)

Это сработало очень хорошо и должно работать с любой другой функцией

0 голосов
/ 21 ноября 2016

Мой снимок экрана:

enter image description here

У меня была такая же проблема.Найти и заменить работает, но не очень приятно.Мое решение:

перейдите на вкладку «Данные»> «Редактировать ссылки»> нажмите «Открыть исходный код», чтобы решить эту проблему

...