Access.Application.Eval()的奇怪行为

时间:2011-06-22 13:46:27

标签: vba ms-access access-vba

解释为什么Access.Application.Eval()(通常缩写为Eval())产生的结果不同于在这种情况下仅评估原始表达式:

Debug.Print Round(.575 * 100)
 57 
Debug.Print Eval("Round(.575 * 100)")
 58 

编辑:为了解决GSerg的答案,以下内容仍会返回不同的结果:

Debug.Print Eval("Round(CSng(.575) * 100)")
 57 
Debug.Print Round(CSng(.575) * 100)
 58 

5 个答案:

答案 0 :(得分:6)

该乘法在Eval()下返回不同的产品,但我不明白为什么。

Debug.Print (.575 * 100) < 57.5
True

Debug.Print Eval("(.575 * 100) = 57.5")
-1

在第一种情况下,产品小于57.5,因此Round()会将其舍入到57.

在第二种情况下,产品等于57.5,因此Round()将采用其标准的“round to even”方法来收益58.

编辑:Eval()将文字值强制转换为其他数据类型,这一切都是正确的。

? TypeName(.575)
Double

? Eval("TypeName(.575)")
Decimal

? Round(CDec(.575) * 100)
 58

答案 1 :(得分:4)

这是因为浮动精度不同。

在一种情况下,常量被识别为Double s,而另一种情况被识别为Single s。

? math.round((.575! - Int(.575!)) * 100)
 58 
? math.round((.575# - Int(.575#)) * 100)
 57 

答案 2 :(得分:2)

GSerg让我思考。我开始相信Jet在调用Eval时会尝试将十进制文字强制转换为Currency类型,而VBA会将十进制文字强制转换为Double类型。一个很好的例子:

? Math.Round(.575 * 100)
 57 
? Math.Round(CSng(.575) * 100)
 58 
? Math.Round(CDbl(.575) * 100)
 57 
? Math.Round(CCur(.575) * 100)
 58 

? Eval("Round(.575 * 100)")
 58 
? Eval("Round(CSng(.575) * 100)")
 57 
? Eval("Round(CDbl(.575) * 100)")
 57 
? Eval("Round(CCur(.575) * 100)")
 58 

答案 3 :(得分:1)

我不使用Access,但我猜测Eval会将表达式计算为Access表达式,以便Round和Int函数的运行方式可能与VBA版本不同?

我从苦涩的经验中知道,VBA的Round()函数使用了舍入到舍入的舍入方法(也就是Banker的舍入),而不是更常见的从零开始的五舍五入(也称为对称)算术舍入方法。

答案 4 :(得分:0)

如果在Access中运行以下SQL表达式,则得到58:

select Round((.575 - Int(.575)) * 100) as MyValue

如果在Access(以及任何Office VBA IDE)的立即窗口中运行以下语句,则会得到57:

Round((.575 - Int(.575)) * 100)

所以,这让我相信VBA有一种不同的方式来做Round而不是Access,可能更适用于JET。

现在,为什么 与众不同?不知道......会选择比我技能更高的人。