【发布时间】:2021-09-07 10:24:10
【问题描述】:
在 VBA 中,我习惯于使用 Evaluate() 计算一列的值,这是另一列的函数,以便不使用循环。例如,要评估第 2 列,其值是第 1 列值的指数,我会写(这里限于前 10 行):
Dim rng1 As Range
Dim rng2 As Range
Set rng1 = Worksheets("Sheet1").Range(Cells(1,1),Cells(10,1))
Set rng2 = Worksheets("Sheet1").Range(Cells(1,2),Cells(10,2))
rng2 = Evaluate("EXP(" & rng1.Address & ")")
我现在想以同样的方式处理我自己的函数。为了进行测试,我创建了一个返回输入指数值的函数:
Function TestExpo(alpha) As Double
TestExpo = EXP(alpha)
End Function
我以与之前 Evaluate() 所述相同的方式进行:
rng2 = Evaluate("TestExpo(" & rng1.Address & ")")
我没有收到错误,但 Excel 工作表上什么也没发生。例如,我试图通过在函数名称中输入错误来触发错误:
rng2 = Evaluate("TestEx(" & rng1.Address & ")")
实际上,我在工作表上 rng2 的每个单元格处都出现了“名称”错误。因此,调用函数“TestExpo”有效。我还尝试使用实数而不是 rng1.Address:
rng2 = Evaluate("TestExpo(" & 2 & ")")
并且我在工作表上 rng2 的所有单元格中都得到了正确的 exp(2) 值,因此调用函数并取回单元格中的值就是这样。
我尝试以不同的方式指定输入和输出的类型。例如:
Function TestExpo(alpha) ' No error, but no values on the sheet
Function TestExpo(alpha) As Range ' No error, but no values on the sheet
Function TestExpo(alpha) As Variant ' No error, but no values on the sheet
Function TestExpo(alpha As Range) ' No error, but no values on the sheet
Function TestExpo(alpha As Variant) ' No error, but no values on the sheet
Function TestExpo(alpha As Double) ' Value error for each cell of the range rng2
除了上次使用 alpha As Double 进行的测试外,我没有收到任何错误,但 Excel 表上也没有任何值。
我的想法已经不多了......我试图找到VBA的EXP()函数的代码,以查看如何指定输入和输出,认为如果我在函数中使用相同的类型和参数“ TestExpo”,它可能工作,但我找不到EXP()函数的代码,它可能不是公开的。
有没有人遇到过类似的情况并解决了?
亲切的问候 泽维尔
更新:
感谢您的贡献!我继续前进!
当我使用时,正如@FaneDuru 所建议的那样
rng2 = Evaluate("""=TestExpo(" & rng1.Address & ")""")
每个单元格中都有一个值错误。检查工作表中的单元格,我可以看到每个单元格都归因于公式:
"=@TestExpo($A$1:$A$35)"
我和写作比较
rng2 = Evaluate("""=EXP(" & rng1.Address & ")""")
哪个有效,并归因于每个单元格的公式
"=EXP(@$A$1:$A$35)"
所以@出现在不同的位置。我手动将公式“=@TestExpo($A$1:$A$35)”更正为“=TestExpo(@$A$1:$A$35)”,它成功了!
所以问题是@的位置,我不明白为什么@在使用函数EXP时默认放在括号内的范围前面,但在使用我自己的函数时放在函数名前面.
尽管如此,手动更正单元格中的公式并不方便。受@FaneDuru 提议的启发,我通过以下方式在范围名称后添加 .Cells(1,1).Address(0,0) 来更正我的代码:
rng2 = Evaluate("""=TestExpo(" & rng1.Cells(1,1).Address(0,0) & ")""")
这成功了!
现在,第一个单元格中的公式如下所示:
"=@TestExpo(A1)"
并且单元格地址适应每一行(第2行公式为“=@TestExpo(A2)”,第3行“=@TestExpo(A3)”等)
@ 仍然出现在函数名称的前面,但括号内有一个单元格名称而不是范围,这使得公式有效。
现在我不得不承认我并不真正了解代码语法是如何工作的。事实上,添加 .Cells(1,1).Address(0,0),我希望 rng2 的所有单元格都将引用范围 rng1 的 Cell(1,1),但公式却适应了每个单元格以正确的方式。
所以,我最初的问题已经解决了:
rng2 = Evaluate("""=TestExpo(" & rng1.Cells(1,1).Address(0,0) & ")""")
甚至更简单:
rng2 = "=TestExpo(" & rng1.Cells(1,1).Address(0,0) & ")"
尽管如此,我还是很想了解代码语法是如何工作的——即,如果代码明确引用了 rng1.Cells(1,1).Address(0,0) 中的单元格(1,1),它是如何工作的可能 rng2 的所有单元格都没有引用单元格(1,1),而是引用了正确的单元格(单元格(2,1)、单元格(3,1)等)?
而且我还想了解为什么 @ 在使用函数 EXP 时默认放在范围前面,但在使用我自己的函数时放在函数名前面。有人有想法吗?
【问题讨论】:
-
您确定
rng2 = Evaluate("EXP(" & rng1.Address & ")")按预期工作吗?我刚试了一下,它在所有单元格中输入了第一个值。 -
好的...我再看看。不确定结果是否会因 Excel 版本而异。与此同时,你可能想试试我的回答。毕竟它可能会做你想做的事。
-
这真的很奇怪...我刚刚复制并粘贴了您的确切代码,并且在 A1:A10 中输入了数字 1-10。 B1:B10 中的结果是所有十个单元格中的第一个结果 (2.71828182845905)。
-
感谢您的反馈!这是我的代码,它确实对我有用。见下表: Column1:函数的输入,Col2:使用 Sub TestFR2 (VBA) 的输出,Col3:使用 Excel 公式 =EXP(A1) 复制到其他单元格的输出。 Col 2 和 3 相等。 Sub TestdFR2() Worksheets("sheet1").Activate Dim rng1 As Range Dim rng2 As Range Set rng1 = Worksheets("sheet1").Range(Cells(1, 1), Cells(10, 1)) Set rng2 = Worksheets ("sheet1").Range(Cells(1, 2), Cells(10, 2)) rng2 = Evaluate("exp(" & rng1.Address & ")") End Sub 0 1 1 0.1 1.11 1.11 0.2 1.22 1.22 0.3 1.35 1.35 0.4 1.49 1.49
-
进行这样的重大更改(至少是有意的)是不寻常的(但并非未知)。但也许,他们认为它非常微妙,不会对绝大多数用户造成问题。很抱歉,我无法提供更多帮助。我希望我的建议,至少能给你一些尝试的选择。
标签: excel vba function evaluate