Excel评估函数在使用间接时返回#REF

时间:2011-10-27 21:17:02

标签: excel vba

我有一个查找,它根据特定单元格的值返回一个公式作为文本。

返回的公式(如文本)如下所示:

SUM(INDIRECT("AF"&row()),INDIRECT("AG"&row()))

然后我使用EVALUATE()函数来评估公式,但由于使用INDIRECT()而收到#REF错误。

This Microsoft Support Page是我能找到这个特定问题的唯一参考,它似乎没有提供适当的解决方法。

我怎样才能:a)重构公式以避免使用INDIRECT,或b)让EVALUATE()玩得开心?

修改

查找表看起来像这样:

键入A SUM(间接(“AF”和行()),间接(“AG”和行())) 键入B SUM(间接(“AF”和行()),间接(“AG”和行()),间接(“AH”和行()))

在另一张纸上,单元格B1:200的内容是类型A或类型B.查找根据单元格的值返回公式字符串并将其放入Bx。然后我评估字符串以给我结果。

4 个答案:

答案 0 :(得分:2)

确定第3次尝试答案:

谢谢你的例子:它失败了,因为你试图使用INDIRECT来评估一个命名的公式,而INDIRECT只处理引用而不是公式。

您需要使用EVALUATE,但没有内置的EVALUATE工作表函数(您在定义的名称中使用的EVALUATE是一个古老的XLM宏函数)。
我建议你使用我的EVAL VBA UDF

Public Function EVAL(theInput As Variant) As Variant
'
' if UDF evaluate the input string as though it was on this sheet
' else evaluate for activesheet
'
Dim vEval As Variant
Application.Volatile
On Error GoTo funcfail
If not IsEmpty(theInput) then
If TypeOf Application.Caller.Parent Is Worksheet Then
vEval = Application.Caller.Parent.Evaluate(Cstr(theInput))
Else
vEval = Application.Evaluate(cstr(theInput))
End If
If IsError(vEval) Then
EVAL = CVErr(xlErrValue)
Else
EVAL = vEval
End If
End If
Exit Function
funcfail:
EVAL = CVErr(xlErrNA)
End Function

然后使用带有相对引用的已定义名称,例如typeA = SUM(Sheet3!RC1,Sheet3RC2)。

你应该注意到一些评价的“怪癖”:见 http://www.decisionmodels.com/calcsecretsh.htm

答案 1 :(得分:0)

如果我理解你正在尝试做什么,为什么不直接从细胞中获得resukt ..
我认为你不需要间接因为你只需要公式的文字
(虽然我不确定ROW()应该做什么)
SUM( “AF” &安培;行(), “AG” &安培;行())

答案 2 :(得分:0)

如果您只想使用定义名称在当前行上添加列AF和AG,则只需使用相对引用(在R1C1模式下更容易定义,然后切换回A1) 定义名称AndySum指的是=SUM(RC32,RC33)的公式。然后,无论您在公式中使用AndySum,它都会在该行上添加AF和AG列的内容。

答案 3 :(得分:0)

扩展Charles的答案:此函数将负责查找并评估行号。我假设公式(在您的示例中)仅用于将与返回最终结果的单元格相同的行中的某些值相加。

我的查找表如下所示:

TypeA   SUM(B<r> ,D<r>) 
TypeB   SUM(C<r>,D<r>)

UDF:

Public Function GetAndRunCalc(CalcType As String)
Application.Volatile
    Dim ac As Object, rw, f

    On Error GoTo haveError

    If TypeOf Application.Caller.Parent Is Worksheet Then
        Set ac = Application.Caller
        rw = ac.Parent.Range(ac.Address).Row
        'adjust for your lookup table...
        f = Application.VLookup(CalcType, Sheet1.Range("B4:C5"), 2, False)
        If Not IsError(f) Then
            f = Replace(f, "<r>", rw)
            GetAndRunCalc = ac.Parent.Evaluate(f)
        Else
            GetAndRunCalc = "Type??"
        End If
    Else
        GetAndRunCalc = "Must be called from worksheet cell"
    End If

    Exit Function

haveError:
    GetAndRunCalc = CVErr(xlErrValue)

End Function