![]() ![]() |
|
使用伪代码开发数据表维护屏幕 | |
作者:佚名 文章来源:不详 点击数 更新时间:2008/4/18 14:51:28 文章录入:杜斌 责任编辑:杜斌 | |
|
|
为了使数据表中所存储数据的准确与及时,并提供正确与及时的查询,必须对数据表进行人工维护(包括数据录入),因此必须为之开发数据表维护屏幕作为人机对话的界面。总结各种数据表维护屏幕,我们会发现它们都是大同小异的,既不会十分复杂但也不可能非常简单。一般的数据表维护屏幕都要求有新增(增加新记录)、编辑(记录修改)、删除(记录删除)以及漫游(指记录指针上移、下移、到顶、到底和各种查找记录定位)功能。另外数据表维护屏幕还必须对用户输入的数据进行合法性检查,特别是对输入关键字的合法性检查,我们一定要保持主关键字的完整性与外关键字的参考完整性不然将会对整个数据系统造成极大的混乱。请注意,尽管VisualFoxpro对主关键字的完整性与外关键字的参考完整性提供系统维护,但这只是对数据系统的安全性增加了最后一道防线,并不能替代在开发数据表维护屏幕中对输入关键字的合法性检查,要不然面对 着陌生的VisualFoxpro系统错误对话框,用户会不知所措的。 由于对输入关键字的合法性检查是开发数据表维护屏幕中不可缺少的一部分增加了开发数据表维护屏幕的复杂性,因此有关数据表维护屏幕的代码不可能很简单,一个代码非常"简洁"的数据表维护屏幕其功能总是不健全的,在使用中总是要出问题的。那么如何才能减少开发数据表维护屏幕的时间与精力呢?本人的办法是使用伪代码。因为数据表维护屏幕的代码虽然比较复杂,但是它们都有很强的共性,我们可以预先编写一套可被各种不同的数据表维护屏幕套用的伪代码,以后编写数据表维护屏幕代码时就不再从零开始,而是从伪代码开始。伪代码虽然不能被直接编译运行,但面对着具体的数据表结构和应用要求,大部分开发人员都能轻松地把伪代码改写成正式代码。 以下笔者向大家介绍本人编写的数据表维护屏幕伪代码,它由一个Custum类和一些Procdure构成。为了方便套用伪代码,笔者尽可能地把Form中的嵌入代码外移,在嵌入代码中使用do...。以下伪代码绝大部分无需修 梢阅美词褂茫栊薷牡慕鍪且恍〔糠郑庖恍〔糠钟炙坪跏羌虻サ摹? 下面是使用伪代码设计数据表维护屏幕的具体步骤: 1.先建立如下一个工作面表格 编 号工 作 面 名 称主 索 引 名 称注 释 1 2 3 4 ... 16 这个表格是对整个应用程序的,这里所说的工作面与我们平时所说的有些不一样,它把处于同一工作面但不同主索引的情况也作为不同的工作面,使 用不同的编号。 2.根据工作面表格改写以下伪代码,使之成为可以编译与运行的正式代码。 { 伪代码开始} public theWorkStat theWorkStat=CreateObject("WorkStat") **== 以下工作状态类==** define class WorkStat as custom curWS=1 declare Ai[16],Or[16] ** 以下工作状态定义 **1 { Ai[1]="A1" && 工作面 Or[1]="O1" &&ORDER 序 Ai[2]="A2" && 工作面 Or[2]="" && 自然序,无主索引 ... **16 Ai[16]="A16" Or[16]="O16" } func Get retu curWS endfunc proc Set para p sele (Ai[p]) set order to (Or[p]) curWS=p endproc
func KeyExist para pws,pk local n,y,rec set exact on n=this.Get(); this.Set(pws) if eof().or.bof() rec=-1 els rec=recno() endif seek pk if found() y=.t. else y=.f. endif if rec!=-1 go rec endif this.Set(n) retu y endfunc func Find para pws,pk,IsExact local n,y,rec if IsExact set Exact on else set Exact off endif n=this.Get(); this.Set(pws) if eof().or.bof() rec=-1 else rec=recno() endif seek pk if found() y=.t. else y=.f. if rec!=-1 go rec endif this.Set(n) endif retu y endfunc endfine {伪代码结束} 在程序的适当人口处运行这段代码,运行这段代码后,只要要用的数据表被打开就可以调用以下对象方法。 ⑴ x=theWorkStat.Get() 取得当前工作面号 ⑵ theWorkStat.Set(n)把当前工作面设置成n号 ⑶ x=theWorkStat.KeyExist(n,key) 测试在n号工作面中是否存在关键字key,存在回送T,不存在回送F;此函数不改变现状。
⑷x=theWorkStat.Find(n,key,IsExact)在n号工作面中查找关键字key;查到则定位之并回送T;查不到则不改变现状并回送F;IsExact为T或F决定是否按精确匹配方式查找。以上这些对象方法在以后的伪代码中要被用到,也可以由用户根据需要使用。 3.判定你要设计的数据表维护屏幕的模式 笔者把数据表维护屏幕分为以下三种模式: ⑴新增模式 在该模式下只有新增(增加新记录)功能,大底用于数据录入(也有不少数 据录入要求有对已录入的内容有返回修改的功能,这就必须使用新增+编辑 模式),笔者开发的驾驶员教育管理程序中的磁卡考勤录入与手工考勤录入 就是很典型的新增模式。 ⑵编辑模式 在该模式下只有编辑、删除与漫游功能而无新增功能。在驾驶员教育管理 程序中的档案修改就是编辑模式。 ⑶新增+编辑模式 在该模式下有新增、编辑、删除与漫游功能,可以说是全功能的。这种模式使用面最广,占所有数据表维护屏幕的一半以上。 4.根据选定的模式改写伪代码,使之成为可以编译与运行的正式代码。 ㈠新增模式 {伪代码开始} priv m.xzok priv m.key,m.key1,m.key2,m.key3,m.KeyText m.xzok=.f. m.key="" m.key1="" m.key2="" m.key3="" m.KeyText="" { open .... && 打开有关的数据表 } scatter memvar blank &&生成与字段相应的内存变量 do ToAppe do form XXX.scx close data all retu *** 关键字输入确认 proc KeyOK { m.key=f(m.key1,m.key2,m.key3) if !theWorkStat.KeyExist(n,m.key) m.FDkey=m.key **m.FDkey为与数据表的主关键字字 段相对应的内存变量应,把它修改为 **m.主关键字字段名。 m.KeyText=f(m.key) m.xzok=.t. else =messagebox(...) endif } retu *** 新增 proc sz if m.xzok appe blank gather memvar && 将与字段相应的内存变量送入字段 do ToAppe endif retu *** 存盘结束 proc cpjs if m.xzok appe blank gather memvar endif retu *** 放弃结束 proc fqjs retu *** 进人新增 proc ToAppe scatter memvar blank { m.KeyText=f(m.key) m.key="********" m.key1=... m.key2=... m.key3=... ..... } m.stat=1 m.xzok=.f. retu {伪代码结束}
其中m.key用以存储主关键字,在以上海市交通安全教育管理程序为例,其值可为"13100000001",第一个"1"表示类别正式,随后的"3100000001"表示证号;其中m.key1,m.key2,m.key3用以存 储合成主关键字各关键字,它们被绑定到Form中的控件上,在程序中m.key1其值可为1,m.key2其值可为"3100000001",m.key3不用; 其中m.KeyText用以存储说明主关键字的文本,它被绑定到Form中的只读文本框上,在程序中其值可为"类别:正式证号:3100000001"。 另外在Form设计中在关键字输入部分的最后要放上关键字输入确认按钮,并在其中嵌入代码doKeyOK和thisform.refresh。 对于Form中的其它和数据表中的非关键字字段对应的控件都与m.字段名绑定,这些内存变量已有scatter命令产生,可放心使用。 最后把doxz和thisform.refresh嵌入新增按钮中,docpjs嵌入存盘结束按钮中,把dofqjs嵌入放弃结束按钮中。 ㈡ 编 辑 模 式 { 伪 代 码 开 始} priv m.key,m.key1,m.key2,m.key3,m.KeyText,m.oldkey,m.FDkey m.key="" m.key1="" m.key2="" m.key3="" m.KeyText="" m.oldkey="" m.FDkey="" { open .... } go top if eof() close data all retu endif do ToEdit1 { do form XXX.scx } pack close data all retu *** 关键字输入确认 proc KeyOK { m.key=f(m.key1,m.key2,m.key3) if m.key==m.oldkey.or.!theWorkStat.KeyExist(n,m.key.t.) m.FDkey=key m.KeyText=f(key) else =messagebox(...) endif } retu *** 删除 func sc dele go top if eof() return .t. endif do ToEdit1 return .f. retu *** 漫游 proc my { repl FDkey with m.FDkey 漫游代码... } do ToEdit1 retu *** 结束 proc js repl FDkey with m.FDkey retu *** 进人编辑,仅用于编辑模式 proc ToEdit1 { m.FDkey=FDkey m.oldkey=FDkey } m.key=m.oldkey { m.KeyText=f(m.key) m.key1=f1(m.key) m.key2=f2(m.key) m.key3=f3(m.key) } retu {伪代码结束} |
|
![]() ![]() |