MS Access复合大小比较问题:为何连续比较返回错误结果?
为什么Access中连续比较的IIf表达式返回错误结果?
这个问题的核心在于Access的表达式引擎(Jet SQL/VBA)不支持数学里的链式比较写法,它对a >= b >= c这类表达式的解析逻辑和你预期的完全不一样,咱们一步步拆解来看:
1. 错误表达式的执行逻辑:IIf(Date()>=#3/16/2018#>=Date()-30,1,0)
Access不会把这个表达式解析成Date()>=#3/16/2018# AND #3/16/2018#>=Date()-30,而是从左到右分步计算:
- 第一步:先计算最左边的比较
Date()>=#3/16/2018#,得到一个布尔值(Access里True等价于-1,False等价于0)。假设当前日期在2018年3月16日之后,这个结果就是True(也就是-1)。 - 第二步:把第一步的布尔结果和右边的
Date()-30做比较,也就是变成了-1 >= Date()-30。Date()-30是一个远大于-1的正数,所以这个比较结果是False,最终IIf返回0。
2. 正确表达式的逻辑:IIf(Date()>=#3/16/2018# AND #3/16/2018#>=Date()-30,1,0)
用AND明确拆分两个条件后,Access会分别计算:
Date()>=#3/16/2018#(判断当前日期不早于目标日期)#3/16/2018#>=Date()-30(判断目标日期在当前日期的30天范围内)
然后取两个条件的逻辑与,只要都满足就返回1,这完全符合你的预期。
3. 更奇怪的情况:IIf(Date()<=#3/16/2018#<=Date()-30,1,0)返回1
同样用分步计算来解释:
- 第一步:计算
Date()<=#3/16/2018#,当前日期在2018年之后的话,结果是False(也就是0)。 - 第二步:把
0和Date()-30做比较,表达式变成0 <= Date()-30。Date()-30是正数,0 <= 正数显然是True,所以IIf返回1,这就是你看到的意外结果。
总结
Access的表达式引擎不支持链式比较语法,如果你需要同时判断多个范围条件,必须用AND(或OR)来明确组合每个独立的比较条件,否则会把前一个比较的布尔结果(数值化的-1或0)和下一个值做数值对比,完全偏离你的逻辑预期。
内容的提问来源于stack exchange,提问作者Joshu's Mu
相关产品推荐
相关产品推荐

