ACCESS常用的窗体查询方法及实例
五. 主子窗体交叉表查询实例
这种方法对应的实例数据库是:“常用窗体查询3.MDB”。 交叉表查询通常作为统计之用,所以查询条件少了一些。
一般学习ACCESS的人,都有可能会被ACCESS的向导误导,以为子窗体控件里面一定要放一个子窗体。其实不是,在我的这个例子里,子窗体的对象其实就是交叉查询,如下图。
刘小军(Alex)2003-5
21
ACCESS常用的窗体查询方法及实例
一直有人问,对于交叉表这样字段数量不固定的,怎样在子窗体中显示。其实,直接在子窗体里显示交叉表本身是最简单的办法。
另一种方法是事先设计一个包含很多未绑定字段文本框的数据表窗体,在显示之前,先用VBA设置窗体的“记录源”和各文本框的“控件来源”,同时还要控制没有字段可以显示的那些列要隐藏,然后再显示出来。但这样设计要求编写比较多的代码,只适合比较熟悉VBA的人使用。(我在这个例子的报表中设计了类似的代码,可以参考。)
1. 按钮设计
1.1 查询按钮
先看一下没有条件的交叉表查询的SQL语句:
TRANSFORM Sum(存书查询.单价) AS 单价之Sum SELECT 存书查询.类别 FROM 存书查询 GROUP BY 存书查询.类别 PIVOT Format([进书日期],\再看一下设置了条件的交叉表查询的SQL语句:
TRANSFORM Sum(存书查询.单价) AS 单价之Sum SELECT 存书查询.类别 FROM 存书查询 WHERE (((存书查询.单价)>=5)) GROUP BY 存书查询.类别 PIVOT Format([进书日期],\可见,WHERE是被插在中间的,所以我在生成SQL语句时要用如下代码:
strSQL = \存书查询.单价) AS 单价之Sum SELECT 存书查询.类别 FROM 存书查询 \strSQL = strSQL & \strSQL = strSQL & \存书查询.类别 PIVOT Format([进书日期],'yyyy/mm')\注意,在字符串中间要留一些空格,比如“FROM 存书查询”的后面,如果不留,SQL语句中“存书查询”和“WHERE”会连在一起。这样肯定是错的。
'显示交叉表的内容,不能直接刷新 Me.存书查询子窗体.SourceObject = \ Me.存书查询子窗体.SourceObject = \查询.存书查询_交叉表\这里也是一些人容易犯错的地方。因为子窗体里是查询对象,用
Me.存书查询子窗体.Requery 这样的语句是不能更新显示内容的。而要用SourceObject才能更新。如果子窗
刘小军(Alex)2003-5
22
ACCESS常用的窗体查询方法及实例
体对象是窗体,而你又用DAO改变了作为子窗体记录源的查询的SQL语句,也要用这种方法来更新显示内容。
'刷新计数和合计显示 Me.计数 = DCount(\存书查询_交叉表\ Me.合计 = DSum(\单价]\存书查询\由于子窗体对象不是窗体了,自然就没有什么窗体页脚来让你设计合计字段。所以用只好用Dcount和Dsum来统计了。 其他按钮的代码都有注释,我就不专门讲了。
2. 报表设计
为了适应交叉表查询列数不固定的情况,我在页面页眉、主体、报表页脚都设计了一些名称有规律的标签、文本框。
'打开查询 Set rst = CurrentDb.OpenRecordset(\存书查询_交叉表] WHERE 1=2\ '记录字段总数 intFieldsNum = rst.Fields.Count 可能大家对“WHERE 1=2”这个条件比较迷惑,其实这是为了让这个rst没有任何记录,因为我们需要的不是记录,只是各个字段的名字。这样也可以少占用一些内存。
其他代码已经有注释了,我就不在这里解释。
3. 方法总结
①在子窗体中直接使用交叉表作为子窗体源对象是最简单的方法。 ②交叉表查询中,日期类型的字段不能引用窗体上的控件作为准则。例如:
Between [FORMS]![存书查询窗体]![进书日期开始] And [FORMS]![存书查询窗体]![进书日期截止] ACCESS会报告错误,但是可以用确定的日期常数作为条件,例如:
Between #2001-1-1# And #2001-12-31# 所以要用DAO的方法来修改交叉表查询的SQL语句。
③以交叉表制作的报表,由于字段数不确定,所以设计起来太麻烦,实用性不强。最好是把交叉表数据导出到EXCEL里再进行处理。
刘小军(Alex)2003-5
23