【问题标题】:Does .Value = .Value act similar to Evaluate() function in VBA?.Value = .Value 的行为是否类似于 VBA 中的 Evaluate() 函数?
【发布时间】:2013-07-18 17:07:33
【问题描述】:

考虑以下sn-p。它将相同的公式写入两个单元格A1 和A2

Sub Main()
    With Range("A1")
        .Formula = "=1+1"
    End With

    With Range("A2")
        .Formula = "=1+1"
        .Value = .Value
    End With
End Sub

第二个with 块使用.Value = .Value 计算/执行公式,因此公式从公式栏中消失。请参阅 hiding formulas from formula bar 以获得支持性参考。

现在,用块添加另一个

With Range("A3")
     .Formula = "=1+1"
End With
Range("A4") = Evaluate(Range("A3").Formula)

您将公式添加到单元格 A3,然后新单元格的公式将 Evaluated() 放入另一个单元格 A4。结果如图所示

我认为上述类型表明.Value = .Value 和Evaluate() 做同样的事情。

但是,下面的代码使用上述两种方法从关闭的工作簿中提取值。我为此示例创建了一个工作簿book9.xlsm,并在单元格A1 中添加了hello。 book9.xlsm 是我要从中提取A1 值的那个。考虑代码

Sub PullValue()
    With Range("A1")
        .Formula = "='C:\Users\admin\Desktop\[book9.xlsm]Sheet1'!A1"
    End With

    With Range("A2")
        .Formula = "='C:\Users\admin\Desktop\[book9.xlsm]Sheet1'!A1"
        .Value = .Value
    End With

    Range("A3").Formula = "='C:\Users\admin\Desktop\[book9.xlsm]Sheet1'!A1"
    Range("A4") = Evaluate(Range("A3").Formula)
End Sub

第一个with 块将公式放入单元格的A1 值中,来自book9.xlsm。它被执行,因此拉取的值为hello,但公式栏显示实际的.Formula,即C:\...。

第二个with 块使用上面演示的.Value = .Value 来评估公式并通过将公式替换为结果来隐藏公式。

Range("A3") 与第一个 with 块相同。

现在(A4)我遵循与第一个示例相同的原则(此问题中的第一个 sn-p)到Evaluate() 公式但是这次它不起作用。

请查看每个激活的单元格值和公式栏

所以现在,我不能说.Value = .Value 等于Evaluate()。

Evalutate() 的评论说可以和公式一起使用。但在我展示的示例中它不起作用。

Evaluate() 中用作参数的公式是否受到限制?我一直认为 Evaluate 非常强大,但事实证明.Value = .Value 实际上更强大。尽管它们非常相似,但它们在某种程度上有所不同(但我认为这可能是我的错,因为我为此示例选择的公式可能受到限制或限制)。我想我已经展示了是什么让它们同时相似和不同。它仍然像 50%/50%,我无法准确判断它们是否相同。如果有人能够解释这里缺少什么,那就太好了。

【问题讨论】:

  • @lori_m 我已经回滚了你的编辑。请不要从根本上改变帖子的含义,特别是如果您只是“猜测”问题是什么。有关详细信息,请参阅this meta discussion。
  • Evaluate() 当引用的单元格在一个封闭的工作簿中时,恐怕会失败。如果您打开参考的书,那么它会再次正常工作。这是 Evaluate 函数的工作方式,它无法从合上的书中读取。

标签: excel function vba comparison evaluate


【解决方案1】:

.value 和 Evaluate 不一样。
Excel 为每个使用的单元格同时维护一个值和一个公式字符串,您可以使用 Range.Value 和 Range.Formula 独立获取这两者。
您使用 Application.Evaluate 来评估一个字符串,该字符串被评估为活动工作表上的公式(因此实际上使用 Worksheet.Evaluate 而不是 Application.Evaluate 更好,而且它也更快)。
使用 Rng1.Value= Rng2.Value 将 Rng2 中的值复制到 Rng1 并覆盖 Rng1 的公式。
使用 Rng1.Value=Evaluate(rng2.Formula) 要求 Excel 从 rng2 检索公式字符串,对其求值并将结果返回给 Rng1。

Evaluate 方法的工作方式与单元格中的公式不同:它有许多您需要注意的“怪癖”(包括它不适用于引用外部公式的公式)已关闭的工作簿):请参阅 my blog post for details
通常使用 .Value2 而不是 .Value 更好:请参阅 Value vs Value2 for details

【讨论】:

  • +1 - 我不知道 .Value2 比 .Value 快。感谢您的精彩回答以及博文。
【解决方案2】:

.Value = .Value 和 Evaluate() 不同。

我认为您对对象及其默认属性有些混淆。

始终牢记这两个概念:

  1. VBA 允许您在不指定对象的情况下使用属性和方法。 VBA 将使用它们的默认对象。例如,当您使用Evaluate() 时,您实际上使用的是Sheet1.Evaluate()。

  2. VBA 允许您在不指定属性的情况下使用对象。 VBA 将使用它们的默认属性。例如,当您使用Range("A1") = 1 时,您实际上使用的是Range("A1").Formula = 1。 (你居然用Sheet1.Range("A1").Formula = 1!)

回到您的示例,当您执行.Value = .Value 时,实际上您执行的是Range("A2").Value = Range("A2").Value。单元格的Value属性可以是数字、字符串、错误等。当它是数字时,可能是错误的数字,这不是公式中的正确结果该单元格(例如,因为您禁用了自动计算)。所以.Value = .Value 等价于.Formula = "<xxx>",其中<xxx> 是在单元格上计算的最后一个值。

当您执行Range("A4") = Evaluate(Range("A3").Formula) 时,您要求 Excel 计算公式并将结果分配给范围 A4 的 Formula 属性(因为公式属性是范围对象的默认属性。)

【讨论】:

  • 所以根据你的最后一句话 Range("A4") 实际上应该说 hello 而不会抛出错误。是否因为 Evaluate 无法从已关闭的工作簿中提取值而引发错误?
  • 是的。当公式引用已关闭的工作簿时,即使它们已关闭,Excel 也能很好地查看它们。 Evaluate 方法适用于跨工作簿的数据,但前提是它们已经打开。如果您知道您的下一个 Evaluate 将尝试访问另一个工作簿上的数据,您的宏应检查工作簿是否已关闭并打开它。但是性能会比公式慢得多(即使使用ScreenUpdating = False),因为您的宏会打开整个工作簿,而公式只能访问已关闭文件中所需的数据。
  • 您的回答中是否有任何支持(You actually use Sheet1.Range("A1").Formula = 1!) 的参考资料?您是如何确定公式是 Range 的默认值的?
  • @mehow 我没有任何参考资料。我认为这是因为Range("A2") = "=A1" 有效,并且因为其他类似的行为,但我可能是错的。
  • 谢谢。闲暇时间请see this,可能你会感兴趣
【解决方案3】:

.Value = .Value(在单元格的 With 块内)只是将单元格的值设置为其当前值,如果有公式,则覆盖并删除其公式。 .Value 属性仅表示单元格的当前值。如果单元格包含尚未计算的公式,例如如果计算已关闭,则可能不会返回公式结果,而是返回单元格之前的值。

Excel.Application.Evaluate 接受一个字符串值,评估字符串的内容,就好像它是一个公式或单元格的名称,并返回该单元格或公式的值。如果您传递一个无法映射到 Excel 单元格名称或不是有效公式的字符串,您将收到错误消息。 Evaluate 的目的是允许评估动态创建的公式,而无需将公式写出到单元格中。如果传递一个公式,即使关闭工作簿计算,它也应该返回一个结果,但如果传递一个名称,我希望它返回单元格的当前值,如果工作簿计算关闭,该值可能不会反映被引用单元格的期望值。

大概由于单元格的.Value和Evaluate()可以返回不同的结果,所以工作表公式求值引擎和Application.Evaluate()引擎是不同的,或者至少有一些不同的元素。

【讨论】:

    【解决方案4】:

    评估是一个函数 以及在函数后使用点(。)的东西,称为属性。所以 ".Value",".Formula",".Text" 是您在此处使用的 Range 的属性。

    不要混淆这两件事。

    函数接受输入,使用其输入变量执行操作并返回结果。它适用于为其配置的数据类型。

    .value 是一个不依赖于数据类型的通用属性。它可以是字符串、数字、浮点数等。

    所以你有可能从 1 中得到错误,而其他工作绝对没问题。

    【讨论】:

      猜你喜欢
      • 2018-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 2014-06-22
      • 2017-12-20
      相关资源
      最近更新 更多