Excel VBA 当引用未激活时评估函数错误 Sheet 命名范围
Excel VBA Evaluate Function Wrong When Reference is Not Active Sheet for Named Range
编辑了更好的例子
我正在尝试使用 Evaluate 函数来计算命名范围的公式引用。但是,在使用 Evaluate 函数时,如果您没有明确声明 sheet 引用和单元格引用,它将假定活动 sheet 作为单元格引用。这会导致错误的结果
在我的实际项目中,我试图只评估命名范围公式的一部分,因此它变得更加棘手。
使用我正在尝试做的一个基本示例,假设您在 Sheet 1 个名为 MyCell 的单元格 A1 中有以下公式:
="Don't evaluate this part"&"My Result Is " & A2
如果 Active Sheet 是 Sheet 2 而你 运行 下面的代码它会给你错误的结果(这是一个说明问题的快速而肮脏的例子)
Dim s As String
s = Replace(Range("MyCell").Formula, """Don't evaluate this part""&", "")
Debug.Print Evaluate(s)
它没有给我 Sheet 1 的单元格 A2 中的值,而是给我 Sheet2 的单元格 A2 中的值。
对此有什么想法吗?
这是我发现的最接近的,但这不是我的确切问题(尽管标题相似)并且它没有提供解决方案:
您遇到的问题是,根据设计 Excel 将假定所有非特定单元格引用都引用现有工作sheet。这就是为什么建议尽可能在所有代码中明确说明工作sheet。
最干净的方法(已通过一些 MSDN 定义搜索验证)是直接明确说明工作sheet而不激活它:
Sub test2()
Debug.Print Range("MyCell").Worksheet.Evaluate(Range("MyCell").Formula)
End Sub
或者,此代码会将活动作品sheet更改为正确的作品,然后在评估后将其改回。 不推荐在没有情有可原的情况下像下面的代码那样执行 sheet 激活。连这里都没有。
Sub test()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim s As String
s = Replace(Range("MyCell").Formula, """Don't evaluate this part""&", "")
Range("MyCell").Worksheet.Activate ' Don't remember if .Worksheet or .Parent ??
Debug.Print Evaluate(s)
ws.Activate
End Sub
正如 ThunderFrame 在评论中所指出的,重要的是要记住,此代码假定 MyCell 是问题中所述的简单单元格引用。否则,您将需要使用其他方法来确定目标工作sheet 名称(或对其进行硬编码)。
你的线路:
Debug.Print Evaluate(Range("MyCell").Formula)
相当于:
Debug.Print Evaluate("=""My Result Is "" & A2")
这就是为什么您根据 ActiveSheet 中 A2 的值获得结果的原因。
如果要检查公式的内容,可以使用这一行:
Debug.Print [MyCell].Formula
如果您想要 MyCell 相对于 Sheet1 的值,那么您有 2 个选项:
1 - 使用 Debug.Print Range("Sheet1!MyCell").Value
2 - 使用 Debug.Print Sheet1.Range("MyCell").Value
几乎总是使用 Worksheet.Evaluate 而不是默认的 Application.Evaluate 更好:正如 Mark Balhoff 指出的那样,您可以控制不合格的引用。
但是 Worksheet.Evaluate 通常也是 Application.Evaluate 的两倍。
有关详细信息,请参阅我的博客 post
https://fastexcel.wordpress.com/2011/11/02/evaluate-functions-and-formulas-fun-how-to-make-excels-evaluate-method-twice-as-fast/
编辑了更好的例子
我正在尝试使用 Evaluate 函数来计算命名范围的公式引用。但是,在使用 Evaluate 函数时,如果您没有明确声明 sheet 引用和单元格引用,它将假定活动 sheet 作为单元格引用。这会导致错误的结果
在我的实际项目中,我试图只评估命名范围公式的一部分,因此它变得更加棘手。
使用我正在尝试做的一个基本示例,假设您在 Sheet 1 个名为 MyCell 的单元格 A1 中有以下公式:
="Don't evaluate this part"&"My Result Is " & A2
如果 Active Sheet 是 Sheet 2 而你 运行 下面的代码它会给你错误的结果(这是一个说明问题的快速而肮脏的例子)
Dim s As String
s = Replace(Range("MyCell").Formula, """Don't evaluate this part""&", "")
Debug.Print Evaluate(s)
它没有给我 Sheet 1 的单元格 A2 中的值,而是给我 Sheet2 的单元格 A2 中的值。
对此有什么想法吗?
这是我发现的最接近的,但这不是我的确切问题(尽管标题相似)并且它没有提供解决方案:
您遇到的问题是,根据设计 Excel 将假定所有非特定单元格引用都引用现有工作sheet。这就是为什么建议尽可能在所有代码中明确说明工作sheet。
最干净的方法(已通过一些 MSDN 定义搜索验证)是直接明确说明工作sheet而不激活它:
Sub test2()
Debug.Print Range("MyCell").Worksheet.Evaluate(Range("MyCell").Formula)
End Sub
或者,此代码会将活动作品sheet更改为正确的作品,然后在评估后将其改回。 不推荐在没有情有可原的情况下像下面的代码那样执行 sheet 激活。连这里都没有。
Sub test()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim s As String
s = Replace(Range("MyCell").Formula, """Don't evaluate this part""&", "")
Range("MyCell").Worksheet.Activate ' Don't remember if .Worksheet or .Parent ??
Debug.Print Evaluate(s)
ws.Activate
End Sub
正如 ThunderFrame 在评论中所指出的,重要的是要记住,此代码假定 MyCell 是问题中所述的简单单元格引用。否则,您将需要使用其他方法来确定目标工作sheet 名称(或对其进行硬编码)。
你的线路:
Debug.Print Evaluate(Range("MyCell").Formula)
相当于:
Debug.Print Evaluate("=""My Result Is "" & A2")
这就是为什么您根据 ActiveSheet 中 A2 的值获得结果的原因。
如果要检查公式的内容,可以使用这一行:
Debug.Print [MyCell].Formula
如果您想要 MyCell 相对于 Sheet1 的值,那么您有 2 个选项:
1 - 使用 Debug.Print Range("Sheet1!MyCell").Value
2 - 使用 Debug.Print Sheet1.Range("MyCell").Value
几乎总是使用 Worksheet.Evaluate 而不是默认的 Application.Evaluate 更好:正如 Mark Balhoff 指出的那样,您可以控制不合格的引用。 但是 Worksheet.Evaluate 通常也是 Application.Evaluate 的两倍。 有关详细信息,请参阅我的博客 post https://fastexcel.wordpress.com/2011/11/02/evaluate-functions-and-formulas-fun-how-to-make-excels-evaluate-method-twice-as-fast/