【问题标题】:Excel Evaluate Function Returns #REF When Using Indirect使用间接时 Excel 求值函数返回 #REF
【发布时间】:2011-12-16 21:01:05
【问题描述】:

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

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

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

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

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

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

编辑

查找表如下所示:

类型 A                   SUM(INDIRECT("AF"&row()),INDIRECT("AG"&row()))
B 类                   SUM(INDIRECT("AF"&row()),INDIRECT("AG"&row()), INDIRECT("AH"&Row()))

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

【问题讨论】:

  • 您将 evaluate() 作为 XLM 宏的一部分,还是在工作表单元格中使用?
  • 我实际上是在一个命名范围中使用它,然后我从一个单元格中调用它。
  • 你能显示查找吗?不清楚 row() 的上下文是什么。我不确定您是否需要间接和评估,因为它们都具有相似的目的......
  • 可能是ROW根据它的参数返回一个array?也就是说,ROW() 返回一个包含当前选定行号的单元素数组。 ROW(a42:q99) 返回 {42; 43; ...; 99}等。只是一个评论,因为我没有方便的Excel来处理这个......
  • @Tim,请使用查找表查看我的编辑。 INDIRECT 不计算公式,仅将文本解释为单元格引用。这就是为什么我需要两者。

标签: excel vba


【解决方案1】:

OK 第三次尝试回答:

感谢您的示例:它失败了,因为您尝试使用 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)。

您应该注意 EVALUATE 的一些“怪癖”:请参阅
http://www.decisionmodels.com/calcsecretsh.htm

【讨论】:

  • 这似乎是我试图达到的最接近的结果。非常感谢您的帮助和耐心。
【解决方案2】:

如果我理解您要正确执行的操作,为什么不直接从单元格中获取结果..
我认为您不需要间接的,因为您只需要公式的文本
(虽然我不确定 ROW() 应该做什么)
SUM("AF"&row(),"AG"&row())

【讨论】:

  • Charles, row() 获取对当前行的引用。不幸的是,像这样构建 SUM 是行不通的,因为它需要 INDIRECT 来将您的文本解释为一个单元格。这是不起作用的 =SUM("AF2","AG2") 和起作用的 =SUM(AF2,AG2) 之间的区别。
【解决方案3】:

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

【讨论】:

  • 了解,但并不总是需要添加 AF 和 AG。我已经按照蒂姆的要求编辑了这个问题,但这可能有助于更好地解释我想要完成的工作。感谢您的耐心等待。
  • 那么为什么不使用带有 IF 或 CHOOSE 的查找公式来选择各种风格的已定义名称
  • 因为我的查找表中可能有几百个类型,这将导致几百个定义的名称,以及一个超长的 IF 公式......
【解决方案4】:

扩展 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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 2020-08-01
    • 2011-02-20
    • 1970-01-01
    相关资源
    最近更新 更多