При вызове из UDF Excel VBA Range.Precedents возвращает диапазон, а не его прецеденты. Есть ли обходной путь? - PullRequest
8 голосов
/ 04 апреля 2011

У меня есть эта функция VBA:

Public Function testPrec(target As Range) As String
    testPrec = target.Precedents.Address(External:=False)
End Function

В ячейке C11 у меня есть эта формула:

=C6+C8

Если я вызываю testPrec из непосредственного окна, она работает простоштраф:

?testPrec([c11])
$C$6,$C$8

РЕДАКТИРОВАТЬ: Он также работает нормально, если вызван из не-UDF макрос Sub.Аномалия - это случай UDF.

Если я называю это из таблицы как UDF:

=testPrec(C11)

Я просто получаю "C $ 11".

Кто-нибудь знает, что происходит, или даже лучше, как получить фактические прецеденты из вызова UDF?(Я использую Excel 2007.)

Ответы [ 3 ]

3 голосов
/ 05 апреля 2011

Кажется, что ограничение заключается в том, что любой вызов .Precedents в стеке вызовов, который включает UDF, обрабатывается по-разному. Итак, найдите способ выполнить вызов за пределами стека вызовов, инициированных из UDF: одна мысль состоит в использовании событий. Вот слишком упрощенный пример для демонстрации

В модуле определим

Public strPrecedent As String
Public rngPrecedent As Range

Public Function testPrec(target As Range) As String
    Set rngPrecedent = target
    testPrec = strPrecedent
End Function

В листе определения

Private Sub Worksheet_Calculate()
    If Not Module1.rngPrecedent Is Nothing Then
        Module1.strPrecedent = Module1.rngPrecedent.Precedents.Address(External:=False)
    End If
End Sub

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

2 голосов
/ 04 апреля 2011

Единственный обходной путь, о котором я могу подумать, - это получить target.formula и разобрать его - не очень приятно.

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

Я столкнулся с похожей проблемой: мне пришлось форматировать ячейки, основываясь на том, содержат ли они формулу или постоянное значение. HasFormula позволяет определить, содержит ли ячейка формулу, однако простые вычисления, такие как =123+45, также определяются как формулы (правильно с технической точки зрения, но неправильно с точки зрения финансового моделирования). Поэтому я хотел использовать Precedents в UDF, чтобы увидеть, связана ли данная ячейка с какой-либо другой. Как упомянуто выше, значение Precedents во время выполнения UDF недопустимо, но Мне нужно было знать только, есть ли прецедент , а не какие ячейки они являются.

Поэтому я сравнил свойства Formula и FormulaR1C1, поскольку они различаются только в том случае, если Formula содержит ссылку на ячейку.

Есть одно исключение: если Formula содержит Именованные Диапазоны, тогда Formula и FormulaR1C1 могут быть равны, даже если ячейка ссылается на что-то. (Это не относится к моему случаю, и я не хотел итерировать все имена и проверять, содержатся ли они в Formula внешних кавычках.

...