其它/杂项
浅谈Access中条件表达式Criteria
2017-11-16 16:00:14

  什么是Criteria?可能很多读者都不知道。Access中,Criteria无处不在,无时无刻不在你的代码中出现,可能你每天都要和她打交道无数次。  那么究竟什么才是Critetia,让我们来看下面这个例子:

Forms![窗体_1]![Text0]

  你可能会觉得,这不是一个很标准的表达式吗?没错,这就是Criteria。  之所以我在文中不使用“表达式”来称呼她,是因为Criteria并不是标准的表达式,如果你使用过Eval函数,你就会知道,Eval处理的表达式才是标准的表达式,也正是因为如此,在VBA中文文档中,并没有把Criteria作中文翻译,而是使用了英文的原名。因为她是一种特殊的表达式。    既然我们已经认识了Criteria,我们一定可以回想起,我们在如此多的地方使用过她,在查询中,在窗体中,在报表中,……但是请你回忆一下,是不是每次都是你把Criteria告诉Access,然后她来帮你作处理,有没有你直接求出Criteria值然后自己来使用的?有?没有?有?没有?好好想想,到底有没有?  可能你开始觉得有点疑惑了,好像真的没有。不必疑惑,  因为Access根本没有提供Criteria的求值接口!  没错,Access完全隐藏了Criteria的求值过程,但是Access一定有个函数或者一个函数库来进行Criteria的求值。你可能会问我为什么这么肯定,理由很简单,Criteria包含的内容实在太多,可能是对象的数据,也可能是SQL查询的字段,可能是函数,还可能是……反正表达式生成器里面的那一堆东西,都可以包含在Criteria中,因此Criteria的求值过程并不是一个简单的过程,Access不可能为每个功能单独写段代码来对Criteria进行求值,所以她必定是一个模块,一个Access没有或者说不愿意公开接口的模块。唯一和Criteria有点关系的,可能就是Application对象的BuildCriteria方法了,但这只是一个Criteria生成(确切说是格式化)的方法,最终生成的Criteria,我们还是要通过各种不同的功能、函数传送给Access,以表达我们想要表达的内容,但是这个内容的最终结果是不是正确,我们无从得知,只能从功能和函数返回的值是否符合我们的预期来判断我们的Criteria是否传递正确了。  这太不公平了!  我们居然要隔着靴子挠痒痒!任何一个语言的开发环境都允许我们在调试模式下监视我们的值是否正确传递,但是Criteria,这个我们自己创建的东西,Access居然不允许我们直接查看她的结果。你不让,我偏要!  经过一番尝试,我找到了一种Criteria求值方法。让我们创建一个窗体,添加三个名为Text1、Text2、Text3的文本控件,并且写入以下代码:

Private Sub Text2_AfterUpdate()     Text3.ControlSource = "=" & Text2.Value End Sub

  OK!让我们来执行这个窗体,并按照以下步骤输入:1、Text1输入:我是Text12、Text2输入:[Text1]  你看到了什么?呵呵,不用觉得惊讶,我们“的确”已经计算出了Criteria的值。你还可以尝试输入:Forms![窗体1].Name来看看窗体的名字。看来对象的解读没有问题,那么SQL字段呢?接着我们在这个窗体上绑定一个表,里面包含字段1,字段2,第一条记录是(123,120),然后再打开窗体,照以下步骤操作:1、Text1输入:1002、Text2输入:[字段1]*[字段2]/[Text1]  哈哈,太好了,数据库字段解读一点问题都没有。最后再让我们尝试一下在VBA中获取到这个值。让我们首先把VBA代码中原先的代码删除,加入以下代码:

Private Sub Text2_AfterUpdate()     Text3.Value = EvalCriteria(Text2.Value) End Sub Public Function EvalCriteria(ByVal strCriteria As String) As Variant     Criteria.ControlSource = "=" & Text2.Value     DoEvents     EvalCriteria = Criteria.Value End Function

  在这里,我们在窗体上放置了一个隐藏的文本控件名为Criteria,用于Criteria绑定数据源的中转,那么现在就让我们来运行这个窗体吧。  运行的结果这里就不在赘述了,通过将Criteria当作一个数据源来绑定,我们成功地对Criteria进行了求值,终于踏出了揭开Criteria神秘面纱的第一步。(待续)