VFP 学习、开发漫谈 (22)
对数据进行筛选,是每个应用程序必备的功能之一。下面,介绍一种利用快捷菜单对数据进行筛选的方法,希望对大家的编程开发有所启发。以编写一个合同模板维护表单为例,下图是表单的运行界面,仅显示了采购员“张三”填写的合同模板:
先介绍一下“合同模板.dbf”的结构。主要字段有“模板 ID(Integer AutoInc)”、“模板说明 C(60)”、“采购员 C(10)”、“质量标准 M”、……。
说明:
●“模板id”是主关键字段,是模板的唯一标识。
●“采购员”字段由系统自动维护,每个采购员只能修改自己的模板。
●“通用”模板是公司法律事务部拟定的标准模板,适用于无特殊要求的所有材料,“采购员”字段为空。采购员不能修改和删除“通用”模板。同时,“通用”模板可作为其他模板的基础。在新建自己的模板时,先通过“复制”按钮,将“通用”模板复制一份,然后再对其进行修改形成自己的模板。
现在,要实现的功能是:单击“筛选”按钮,弹出一个快捷菜单,里面显示出所有采购员。选择某个采购员,则仅显示该采购员的合同模板。选择“全部”则取消筛选,显示所有采购员的模板记录。在快捷菜单中,当前采购员的菜单项前有“√”标记,表示记录已按该采购员进行了筛选。
系统的核心代码放在“筛选”按钮的 Click 事件中:
程序代码:
LOCAL aBuyer[1],nNum,cFilter,nMark,i,cBuyer * 获取采购员列表 SELECT DISTINCT 采购员 FROM 合同模板 INTO ARRAY aBuyer WHERE !EMPTY(采购员) nNum = _Tally && 采购员数量 IF nNum = 0 && 若除通用模板外无其他记录,则返回 RETURN ENDIF * 定义菜单(全部,采购员1,采购员2……) DEACTIVATE POPUP mnuFilt DEFINE POPUP mnuFilt SHORTCUT RELATIVE FROM MROW(),MCOL() DEFINE BAR 1 OF mnuFilt PROMPT ' (全部)' DEFINE BAR 2 OF mnuFilt PROMPT '\-' FOR i = 1 TO ALEN(aBuyer) DEFINE BAR i+2 OF mnuFilt PROMPT aBuyer[i] NEXT * 根据表的筛选状态,标记菜单项 cFilter = FILTER('合同模板') nMark = 1 && 默认选定“(全部)” FOR i = 1 TO nNum IF ALLT(aBuyer[i]) $ cFilter nMark = i + 2 && 前两项是“(全部)”和分隔线,所以菜单项要加 2 EXIT ENDIF NEXT SET MARK OF BAR nMark OF mnuFilt TO .t. * 激活菜单 ON SELECTION POPUP mnuFilt DEACTIVATE POPUP mnuFilt ACTIVATE POPUP mnuFilt RELEASE POPUPS mnuFilt * 根据选择的采购员,执行筛选 IF BAR() > 0 SELECT 合同模板 cBuyer = PROMPT() IF cBuyer = ' (全部)' SET FILTER TO ELSE SET FILTER TO EMPTY(采购员) OR 采购员 = "&cBuyer" ENDIF GO TOP THISFORM.Refresh ENDIF为了与大多数软件的习惯保持一致,在为“筛选”按钮指定图标时,我选择了一个“漏斗”图片,然后又在其下方添加了一个小箭头,表示单击该按钮将弹出一个快捷菜单。
另外,在使用 Set Filter To 指定筛选条件时,不要直接使用内存变量。比如:若将代码改为 Set Filter to Empty(采购员) OR 采购员 = cBuyer,将因 cBuyer 是 Local 变量而运行时出错(单击表格时,系统提示“变量 cBuyer未找到”)。当然,将 cBuyer 设为 Public 可以解决变量作用域的问题。但是,这绝对不是一个好方法。
正确的方法是,使用宏替换将 cBuyer 转换为常量,如:SET FILTER TO EMPTY(采购员) OR 采购员 = "&cBuyer"。
对于一个程序员来说,对全局变量的使用应该慎之又慎。Windows是一个多线程、多窗口操作系统,即使在每个表单中定义的全局变量名不同,但由于VFP允许一个表单运行多个实例,那么在该表单的多个运行实例中实际上使用的仍是同一个变量,导致各窗口中的同名变量相互影响,带来逻辑混乱。我一般仅将用户的登录id(gnUserId)、用户名(gcUserName)以及与 SQL Server的连接句柄(gnHandle)定义为全局变量。对于在同一表单中不同控件之间的共用变量,我一般通过将其设置为表单的自定义属性来解决。在VFP中,可以将表单的自定义属性理解为表单变量,它的作用域是表单的所有控件以及表单本身。
[ 本帖最后由 liuxingang28 于 2014-5-16 09:57 编辑 ]