VFP表单问题(一) 1.让VFP表单卸载时显示确认对话框 在表单1的command1的click事件中写入: with thisform 3. 创建表单集时, 没有明确的办法添加已存在的表单到表单集.本文向你展示如何添加已存在的表单到表单集. 假设要添加表单 MyForm 到表单集, 按以下步骤: 1 打开 MyForm. 2 在文件菜单中, 单击另存为类, 并单击保存表单. 3 为新类取一个类名和要保存的类库文件名(.VCX 文件). 4 关闭 MyForm. 5 进入表单设计器,打开你的表单集,单击表单设计工具条中的"查看类",然后单击添加. 6 选择你保存 MyForm 类的类库文件 .VCX, 并单击打开. 7 选择工具条中的 MyForm ,并将该表单类拖放到表单集中. 这样就把 MyForm 类的一个实例添加到了表单集中. 4.想做一个全屏大小的表单,该用什么方法? 答:在form的init时间中加入:thisform.xxx..(某控件).setfocus 5 怎样从表单返加一个值? 可以在模式表单的unload事件中用return来返回一个值。 6. 怎样在表单设计器中把属性或方法添加到表单中? 用表单设计器窗口或属性/事件/激活的方法窗口,从菜单中选择表 单。最初的两个选择是新属性和新方法。选择你想要加入的一个并填写属性 或方法的名称,新建的属性将出现在属性窗口的最底部。 7. 模式表单和非模式表单的区别是什么? 答案5: 模式表单一般地被用来处理错误报告,或者请求用户确认操作等。 在模式表单中,菜单不能使用。如果需要,模式表单也提供应用'等待状态'。 非模式表单提供更多的灵活性,它允许用户通过菜单操作,在表单中移动。 8.表单A调用表单B: 9.为何我设置好Form的ToolTipText属性后,这些提示总是无法显示出来呢? 10.我在pageframe中的一个页中改变了记录指针,但我转到其他的页时, 需要在你的每一页Activate()中放置代码来确信显示当前记录值。 11.深入VFP类设计数据输入表单 数据输入始终是MIS系统的重要问题,许多MIS系统的数据录入没有充分考虑到重复数据或记录有相当多的共同字段值的输入问题。历经2年之后,终于从VFP的类出发,较好的解决了这一问题,并且在《实验室管理系统Labman2001》中得以成功采用。 类是面向对象程序设计方法中极为重要的部分,也是其精髓所在。如果在可视化编程时代不利用面向对象的编程方法,不采用类来进行系统整体规划,事实上是根本没有发挥先进编程工具的优势。利用类的继承性,可以很方便的修改建立在其上的程序,使之全部更新而无需逐一修改代码,如果需要特殊处理,可以在类基础上重新定义事件处理程序。这样节省了大量的开发时间,并且减少了出错的机会。我们以实例来说明。 先设计如图1表单。 表单包括10个按钮和一个核选框。按钮分为两组,一组是浏览记录的,包括“到首”“前翻”“后翻”“到尾”,另一组包括“增加”“清除”“修改”“删除”“恢复”“退出”,分别实现的相应的功能。核选框则用来控制实现哪组功能。当核选框没有选中时,只有“增加”“清除”“退出”可用,选中核选框,则“到首”“前翻”“后翻”“到尾”“修改”“删除”“恢复”可用。当“增加”可用时,在相关文字框中输入字段值,单击“增加”,一条记录加入表中,再次单击时,提示“已存在该关键字记录,请修改!”,如果下一条记录只有编号不同,修改编号即可,如果还有其他不同,也修改,然后单击“增加”,再次增加一条新记录。如果不想利用前面的记录,单击“清除”,所有字段值清空,重新输入即可。如果想修改记录,可以先浏览到相应的记录,先在文字框中修改完毕,然后按“修改”即可。 下面依次介绍按钮的事件代码,其中夹杂着注释: “到首”的click事件代码 if reccount()==0 wait nowait windows("表中记录数为0!!!") return endif ******当表是空的时候,浏览功能无法使用,并提醒增加记录入表。 thisform.cmdtop.enabled=.f. thisform.cmdprev.enabled=.f. thisform.cmdbottom.enabled=.t. thisform.cmdnext.enabled=.t. ****当单击“到首”后,设置“到首”“前翻”失效。 go top ******下面的小段程序在浏览的四个按钮中均有,为节省篇幅计,以后的均省略。标记为prog01。 dimension m.memc[1] **定义数组,容纳一条记录,定义一个元素即可,如果容纳不下,系统会自动增加。 scatter to m.memc memo ***把内存中记录存放在数组中。 m.nlen=alen(m.memc) ***获取一条记录有多少个字段,存放在m.nlen中。 *****建立循环,将字段逐一放置在表单的相应文字框中。 for m.i=1 to m.nlen m.nameinput="thisform."+field(i)+'1'+".value" ***获取相关字段的文字框名字 &nameinput = m.memc[m.i] ***将字段放置相应文字框中 endfor thisform.refresh ***刷新表单。 return “前翻”的click事件代码 if reccount()==0 wait nowait windows("表中记录数为0!!!") return endif thisform.cmdbottom.enabled=.t. thisform.cmdnext.enabled=.t. if recno()==1 thisform.cmdtop.enabled=.f. thisform.cmdprev.enabled=.f. else if bof()==.t. ***单击“前翻”后,如果已经到表开始,设置“到首”“前翻”失效。 thisform.cmdtop.enabled=.f. thisform.cmdprev.enabled=.f. else skip -1 endif endif *******下同prog01 “后翻”的click事件代码 if reccount()==0 wait nowait windows("表中记录数为0!!!") return endif thisform.cmdtop.enabled=.t. thisform.cmdprev.enabled=.t. if eof( )==.t. and bof()==.f. thisform.cmdbottom.enabled=.f. thisform.cmdnext.enabled=.f. skip -1 else if reccount()==recno() thisform.cmdbottom.enabled=.f. thisform.cmdnext.enabled=.f. else if bof()==.t. else skip 1 endif endif endif *******下同prog01 “到尾”的click事件代码 if reccount()==0 wait nowait windows("表中记录数为0!!!") return endif thisform.cmdbottom.enabled=.f. thisform.cmdnext.enabled=.f. thisform.cmdtop.enabled=.t. thisform.cmdprev.enabled=.t. go bottom *******下同prog01 “增加”的click事件代码 dimension m.memc(FCOUNT()) ***读取打开表的字段数,确定数组元素数 m.nlen=FCOUNT() for m.i=1 to m.nlen ***建立循环,将字段值写入数组 m.nameinput="thisform."+field(i)+'1'+".value" m.memc[m.i] = &nameinput ****宏替换,字段值写入数组相应位置 if m.memc[m.i]==NULL wait nowait windows("无效数据") return endif endfor go top m.cfiledname=field(1) ****默认第一字段是主关键字。 locate for &cfiledname==m.memc[1] if found( )=.t. if messagebox("已存在该关键字记录,请修改!",48,"增加")=1 return endif else for m.i=1 to m.nlen m.nameinput="thisform."+field(i)+'1'+".value" m.memc[m.i] = &nameinput endfor thisform.refresh go bottom append blank gather memory from memc return endif “清除”的click事件代码 dimension m.memc(FCOUNT()) m.nlen=FCOUNT() m.cchushi="thisform."+field(1)+'1'+".setfocus" &cchushi scatter to m.memc memo for m.i=1 to m.nlen m.nameinput="thisform."+field(i)+'1'+".value" do case case type("m.memc[m.i]")=='C' m.memc[m.i]="" case type("m.memc[m.i]")=='D' m.memc[m.i]=date() case type("m.memc[m.i]")=='N' m.memc[m.i]=0 case type("m.memc[m.i]")=='T' m.memc[m.i]=time() case type("m.memc[m.i]")=='L' m.memc[m.i]=.T. otherwise m.memc[m.i] ="" endcase &nameinput = m.memc[m.i] endfor thisform.refresh return “修改”的click事件代码 dimension m.memc[1] scatter to m.memc memo m.nlen=alen(m.memc) for m.i=1 to m.nlen m.nameinput="thisform."+field(i)+'1'+".value" m.memc[m.i] = &nameinput endfor thisform.refresh gather memory from memc return “删除”的click事件代码 delete thisform.cmdclear.click return “恢复”的click事件代码 recall return “退出”的click事件代码 thisform.release() 核选框的click事件代码 if reccount()==0 thisform.cmdqueding.enabled=.t. thisform.cmdclear.enabled=.t. thisform.cmdtop.enabled=.f. thisform.cmdprev.enabled=.f. thisform.cmdnext.enabled=.f. thisform.cmdbottom.enabled=.f. thisform.cmdmodify.enabled=.f. thisform.cmddelete.enabled=.f. thisform.cmdrecall.enabled=.f. thisform.cmdclear.click wait nowait windows("表中记录数为0!!!") thisform.check1.value=0 return endif if thisform.check1.value==1 thisform.cmdclear.enabled=.f. thisform.cmdqueding.enabled=.f. thisform.cmdtop.enabled=.t. thisform.cmdprev.enabled=.t. thisform.cmdnext.enabled=.t. thisform.cmdbottom.enabled=.t. thisform.cmdmodify.enabled=.t. thisform.cmddelete.enabled=.t. thisform.cmdrecall.enabled=.t. thisform.cmdtop.click else thisform.cmdqueding.enabled=.t. thisform.cmdclear.enabled=.t. thisform.cmdtop.enabled=.f. thisform.cmdprev.enabled=.f. thisform.cmdnext.enabled=.f. thisform.cmdbottom.enabled=.f. thisform.cmdmodify.enabled=.f. thisform.cmddelete.enabled=.f. thisform.cmdrecall.enabled=.f. thisform.cmdclear.click endif 12、表单的init事件 thisform.refresh set deleted on thisform.cmdqueding.enabled=.t. thisform.cmdclear.enabled=.t. thisform.cmdtop.enabled=.f. thisform.cmdprev.enabled=.f. thisform.cmdnext.enabled=.f. thisform.cmdbottom.enabled=.f. thisform.cmdmodify.enabled=.f. thisform.cmddelete.enabled=.f. thisform.cmdrecall.enabled=.f. thisform.cmdclear.click 13、表单的unload事件 pack use set deleted off close all 上述工作完成后,将表单另存为“类”,将出现图2,填入类名为“数据输入类”,类库为“xgjbase”。 现在数据输入类已经做好,接下来的工作是以数据输入类为表单模板,创建具体的数据输入表单。先从VFP系统菜单的“tools"菜单中选择“options”菜单项,出现图3,单击“forms”帧,在模板类中的“form”前核选框选中,并且在其后找对“数据输入类”的位置。单击“OK”,模板类设置完成。以后新建的表单都是以数据输入类为模板。下面创建一个“借用表”表单,外形如图4, 表单load事件代码为: use 借用表.dbf exclusive 另外增加一个按钮“打印借条”,其click事件代码如下: if thisform.check1.value==1 jy1=thisform.登记序号1.value jy2=thisform.仪器编号1.value jy3=thisform.仪器名称1.value jy4=thisform.借用人1.value jy5=thisform.用途1.value jy6=thisform.借用日期1.value jy7=thisform.归还日期1.value jy8=thisform.经手人1.value jy9=thisform.备注1.value REPORT FORM 仪器借条.FRX NOCONSOLE PREVIEW thisform.check1.value=0 else if messagebox("该资料不存在!",48,"借用表")=1 return endif endif 只需要这么一点代码就可以实现数据输入、编辑等诸多功能,如果不要打印借条,甚至这一段都可以不要,只须表单的load事件便可,是不是很爽啊? 12.如何使用全局变量获取表单的返回值(做的是一个删除对话框)?(注:这个表单完全可以用messagebox()函数来代替。作者的用意是讲述表单怎样返回一个值,格式就是:do form 表单 to 变量。然后调用表单再根据这个变量的值作出相应的反应。采用的是全局变量,比表单间的数值传递与返回好理解掌握。) 创建一个“删除确认”表单。 13.VFP中怎样获取表单的返回值(不使用全局变量) 浏览器不支持嵌入式框架,或被配置为不显示嵌入式框架。 ----在调用自定义的对话框表单时,我们往往需要获得该表单执行后的选择结果或是某些控件的值等等。许多人采用的方法是设置一个全程变量,然后在对话框表单内部修改该标志变量,进而获得需要的结果(说的就是上面的例子)。其实VFP提供了一种更为安全的方法,使得表单不光能够接收参数,而且能够返回值。由于不使用全程变量,表单的通用性和独立性得以增强。要使得一个表单能够返回值,必须满足以下条件: tempvar=’’&&接收表单返回值的变量 (此句不要亦可。) do form test to tempvar &&:调用表单,返回值送入变量tempvar if empty(tempvar) &&若直接关闭了表单则 exit &&表单退出 else wait window ‘表单返回值是’+tempvar endif enddo 二、创建示例表单test 14.设定表单间参数传递及返回变量的代码及其含义:(电脑中有自己做的实例) &&调用查找到的表单'paramask.scx' ,并将cparam1,nparam2 两个参数传递给表单'paramask.scx',并指定表单'paramask.scx'在其Unload 事件过程中使用 RETURN 命令来指定返回值的变量为nretvalue 。(根据范例,在表单'paramask.scx'中,新建属性retvalue,在其 Uload事件中加上代码: return thisform.retvalue 具体代码如下: -------------------------------------------------------------------------- 表单frmPara的“提问”按钮的click事件代码: *****定义常量 #define user_response_loc "用户的回答为:" #define yes_loc "yes." #define no_loc "no." #define maybe_loc "maybe." ******清空回答信息标签 thisform.labRetResponse.caption='' ****取参数 cParam1=thisform.txtpassvalue1.value nParam2=thisform.opgpassvalue2.value ****调用另一表单并向表单'paramask.scx'传递参数,并设置表单'paramask.scx'返回参数 do form locfile('paramask.scx') with cparam1,nparam2 to nretvalue ****根据返回参数设置回答信息标签 DO CASE CASE nretvalue=1 thisform.labRetResponse.caption=user_response_loc+yes_loc CASE nretvalue=2 thisform.labRetResponse.caption=user_response_loc+no_loc CASE nretvalue=3 thisform.labRetResponse.caption=user_response_loc+maybe_loc ENDCASE 表单'paramask.scx'的init事件代码: #define pass_value_loc "该表单不能独立运行,要由表单‘param.scx’调用。" parameters cQuestion,nbuttons if type('cQuestion')='L'.or.type('nbuttons')='L' &&如果没有参数传递,该参数变量自动设置为逻辑.F. endif thisform.txtquestion.caption=cquestion &&在'paramask.scx'上显示表单frmPara上所提出过的问题 *********根据所接收的数据,分情况显示或隐藏三个按钮 DO CASE CASE nbuttons=1 CASE nbuttons=3 CASE nbuttons=4 ENDCASE 在表单'paramask.scx'中,新建属性retvalue 意为返回值 表单'paramask.scx'的uload事件代码: return thisform.retvalue 表单'paramask.scx'的cmdYes的click代码: thisform.retvalue=1 thisform.release 表单'paramask.scx'的cmdNo的click代码: thisform.retvalue=2 thisform.release 表单'paramask.scx'的Maybe的click代码: thisform.retvalue=3 thisform.release |
|