Foxpro 2.5实用编程 郭清华 1995-01-06 本人曾先后编制了企业内部银行帐目管理系统、仓储物资出入库核算系统、基建预决算系统、学生成绩管理系统等大小十几套微型计算机数据库应用系统。经过长时间的对Foxpro 2.5的开发使用,有以下体会: 1,编制一套同样的应用系统,用Foxpro比Foxbase和dBASE要节省至少二分之一的时间,而且用Foxpro 2. 5编制出的软件界面更清晰、友好。 2,Foxpro 2.5编制出的软件可维护性高,软件调试、 修改方便及时,同时因其编译功能大大地提高了系统的安全保密性。 3,Foxpro 2.5的强大的报表制作功能, 几乎可以完成所有的复杂报表的设计应用。 下面将分几个专题分别介绍Foxpro 2.5的几个主要的功能: 一、屏幕生成器, 二、菜单生成器, 三、报表生成器, 四、关系范例查询, 五、编制在线帮助。 一、屏幕生成器 1.启动 在 Command 窗内打入以下命令 Modify Screen 文件名,即出现屏幕生成器画面,同时系统菜单上出现 Screen 项。 2.功能简介 Foxpro 2.5 的屏幕生成器生成的不是 Foxview 生成的 FMT 文件, 因此不能用SET FORMAT TO < 文件名 > 的形式来使用。Foxpro 2.5 生成的实际上是含有FMT 的功能并且更加强大的程序文件,扩展名为.SPR。可以用 DO < 文件名.SPR >的形式来使用 Foxpro 2.5 屏幕生成器生成的程序。 3.使用简介 (1)Screen 菜单 打开 Screen 菜单可以看到有 Screen Layout(屏幕设置),选此功能可以定义一个屏幕; Open All Snippets(打开所有的程序段,如后面将要论述的 Setup,Cleanup,When,Valid 等等); 可以在屏幕的任意位置放置 Box (方框),Field(字段或变量),Text(文本),Push Button(压按钮),Radio Button(无线按钮),Check Box(核对框),Popup(弹出式菜单), List (列表框),Inv. Button(不可见按钮);可以用Bring to Front(居前),Send to Back (居后),Center(居中),Recorder Fields(排列字段顺序),Color(设置颜色)等等功能来选择对象的显示、编辑特性、位置等。 (2)设置字段 可以将光标移至屏幕的相应位置,打开 Screen 菜单选择 Field在屏幕上加入相应的字段或内存变量。注意 Field 对话框中Say,Get,Edit 的使用区别。选择 Say则字段只显示不允许编辑;选择 Get 允许用户编辑;Edit 也允许用户编辑、修改,而且被编辑的区域可以滚动,这将给用户编辑较长的字段带来极大方便。 在 Field 对话框的底部,有对字段进行进一步控制的核对框。选取 When 可以加入一逻辑表达式,使得当该式成立时,才允许编辑当前字段; Valid允许对输入当前字段内容的合法性进行核对; Message后可以加入一条信息,使得当编辑当前字段时屏幕的底部显示该提示信息;Error 后可以加入一条信息,使得当 Valid中的逻辑表达式不成立时显示该信息; Comment 可以加入对该编辑字段进行的说明; Disable 禁止该字段; Refresh仅当字段选择 Say 时才有效,当选此核对框时,记录指针从一个记录移到另一记录该字段,显示的内容将自动地改变; Scroll bar、Allow tabs 仅当字段选择了 Edit 才有效。 (3)设置文本 可以将光标移至屏幕的相应位置,打开 Screen 菜单选择 Text 在屏幕上输入相应的文本。或直接在相应的位置输入文本。完毕后按回车键。 (4)设置压按钮 可以将光标移至屏幕的相应位置,打开 Screen 菜单选择 Push Button。这时出现 Push Button 对话框。在对话框的 Push Button Prompts 区域输入按钮上的提示符。在对话框的右上边,可选择使用 Horizontal 或 Vertical 选择项,以指定按钮在屏幕上的排列是水平还是垂直的。Spacing ... 输入各个按钮之间的间隔,Terminating 的选用,可以决定当前的屏幕在选择了该按钮时是否关闭;Variable 框中应输入一变量名,当选择该按钮时, 该变量的值为1,在多个按钮的情况下,选择了某一按钮, 则该变量的值等于该选择的按钮在这一系列按钮中的排列顺序号;Option 中各选项的使用与设置字段中的介绍相同,在此不再赘述。 (5)设置弹出式菜单、列表、核对框、不可见按钮的方法均可参照以上设置文本、字段、压按钮的设置方法。 在设计好屏幕以后,就可以打开 Program 菜单选择 Generate 产生相应的程序了。在这一过程中,要回答系统提示的诸如是否存盘、输入程序名等简单的问题。 4,举例 向一文件管理数据库中添加记录,该数据库由6个字段构成,其含义分别是来文日期、发文日期、发文单位、文件编号、文件名称和文件内容。 输入屏幕如图所示: System File Edit Database Record Program Window Screen SAMPLE.SCX R: 5 C: 13 ||Move || ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ ┌──────┐ ┃ ┃ │文件登记窗口│ ┃ ┃ └──────┘ ┃ ┃发文日期: 1: mwj(1) 来文日期: 2: m_wj(2) ┃ ┃ ┃ ┃发文单位: 3: mwj(3).. 文件编号: 4: m_wj(4).... ┃ ┃ ┃ ┃文件名称: 5: mwj(5)................... ┃ ┃ ┃ ┃文件内容: 6: mwj(6)................... ┃ ┃ ............................ ┃ ┃ ............................  ┃ ┃ ............................ ┃ ┃ ............................ ┃ ┠─────────────────────────┨ ┃ < 登 记 > ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛ 注:有些变量在屏幕上是看不到全部的,如 1: mwj(1) 、2: mwj(2), 由于它们是日期型,宽度设置为8,实际只能看到 1: mwj( 和 2: mwj( 。 在此为方便说明,画出了变量的全貌。 “确认录入”压按钮中输入的变量名为 mexit ,并且选择 Teminating ; 打开 Screen 菜单,选择 Screen Layout 中的 setup 检测框, 加入以下程序段: SET TALK OFF USE wj mexit=0 DECLARE mwj(6) &&定义一数组对应数据库各字段 mwj(1)=DATE() mwj(2)=DATE() mwj(3)=SPACE(20) mwj(4)=SPACE(60) mwj(5)=SPACE(10) mwj(6)=SPACE(255) 选择 cleanup 检测框,加入以下程序段: IF mexit=1 &&当选择压按钮关闭屏幕时 mexit=1 APPEND BLANK GATHER FROM mwj ENDIF USE CLEAR 用 Generate 产生以上屏幕的程序假定为 sample.spr,那么在数据库中添加记录的程序应如以下所示 yn="Y" DO WHILE UPPER(yn)="Y" DO sample1.spr WAIT "继续输入吗? (Y/N)" WINDOW TO yn ENDDO 当然,可以利用屏幕生成器中的各选项和功能,编制出功能更加丰富、强大的屏幕程序。可以这样讲,数据库应用系统中的所有输入和部分输出,不管要求有多复杂,均可用屏幕生成器来实现。 二、菜单生成器 1.启动 在 Command 窗内打入以下命令 Modify Menu < 文件名 >,即出现菜单生成器画面,同时系统菜单上出现 Menu 项。 2,功能简介 \[1842871] 我们知道,数据库应用系统均具有与以上功能模块类似的结构框图。对于这样的系统功能模块的结构框图的菜单系统,用 Foxpro 2.5 的菜单生成器来生成是以类似填表的形式实现的,易如反掌,而且生成的下拉式菜单美观,迎合了当今计算机应用系统 GUI 界面的潮流。构造菜单时, 可以在菜单生成器画面上填入菜单的名称、子菜单的名称、以及将来生成的应用系统中如果选择了该菜单系统应该执行的命令、程序文件模块等等;还可以预视将要生成的菜单,当对该菜单的形式满意时就可以用 Foxpro 2.5 自动地生成针对该菜单的程序代码,扩展名为 MPR。可以用 DO < 文件名 .MPR > 的形式来使用 Foxpro 2.5 菜单生成器生成的程序。 3.使用简介 在菜单生成器画面上,Prompt 一项可以填入菜单的名称。 可以为该菜单项分配热键(当按此热键时也就等同于选择了该菜单)。分配热键的方法是在指定为热键的字母前加入符号“\<”。Result 是选择了菜单后对该菜单的响应,有四种选择:Subme nu (子菜单),Command (命令),Precedure(过程或程序)以及 Pad Name(系统本身 system 菜单中的一个菜单选项)。 下面对的四种选项分别介绍: SUBMENU 选择了子菜单后,出现子菜单构造画面,与主菜单生成器画面几乎是完全一样的,所不同的是,主菜单生成的在中排列的菜单项将来为水平菜单项,而在子菜单构造画面中的菜单项为垂直状的子菜单项。在子菜单中也可以建立菜单项的分隔线(在 Prompt 中填入的项为“ \- ”)。下面分别列出应在 Prompt 中填入的菜单项和实际生成的菜单形状 ┌──────┐ Prompt │ 系统 │ └──────┘ ┌──────┐ \- │ 帮助 F1 │ ├──────┤ \ []│ └─────┘ │\ │ │ ┌─ Item ─┐ │ │ │ │ │ │ │ │ │ │ └─────┘ └────────────────────┘ System File Edit Database Record Program Window Menu WJ.MNX Prompt Result Options ┌────────────────────┐ ┌────┬┐ │\ │ │ ┌─ Item ─┐ │ │ │ │ │ │ │ │ │ │ └─────┘ └────────────────────┘ 三、报表生成器 1.启动 在 Command 窗内打入以下命令 Modify Report < 文件名 >,即出现报表生成器画面,同时系统菜单上出现 Report 项。 2.功能简介 Foxpro 2.5 系统的报表生成器可以用来设计制作几乎任何的表格, 该系统允许你以非常容易的方法将任何选择的信息放入到报表中。在要设计的报表中,你可以放置表格线、方框、文本、字段(变量)以及经过一系列计算的字段(变量)。报表生成器还具备报表的预视功能,部分实现了“ WHAT YOU SEE IS WHAT YOU GET ”(所见即所得)功能。 3.使用简介 在进入到报表生成器画面后,就可以看到在屏幕的顶端是文件名,接下来是状态行,它反应当前光标所处的位置(坐标)和所处的区域、输入信息的状态。再往下的大片就是制表区,在这一区域有 PgHead(页头)、 PgFoot (页底)和Detail(细节),如果在系统的 Report 菜单中选择了 Title(标题)或 Summary (总结),那么 Title 或 Summary也将出现在该区域。 在使用报表生成器的时候,文本、线、框、字段等均可看做是“对象”,可以对“对象”进行任意的添加、移动、复制、删除等操作。 打开系统的 Report 菜单可以看到主要有如下的功能选项: Page Layout ... 这是对报表进行设置,其中包括报表的尺寸、报表的使用环境等信息。 Page Preview... 报表预视功能。 Data Grouping... 可以对输出的信息进行分组。选中此项后系统要求你输入要分组的字段名,也可以进行多级分组;分组后屏幕的制表区域出现相应的分组数据带。 Title/Summary 可以选择报表是否带有标题 Title(标题)或 Summary(总结),同时选择输出标题后是否换页输出正文、输出正文后是否换页输出总结。 Box Field... Text 框、字段(变量)和文本,即“对象”。 Add line Remove line 可以在报表中添加一行或删除一行。 Bring to Front Send to Back Center 就象屏幕生成器一样,它们是用来布置“对象”的。 在字段对话窗中还有几项比较重要的功能: Calculate 用以建立一个计算字段,该计算基于 End of Report(整个报表)或 End of Page(报表页)。计算的方式可选择: Nothing 不做计算 Count 计数 Sum 求和 Average 求平均 Lowest 求该字段系列中的最小值 Highest 求该字段系列中的最大值 Std.Deviation 方差的平方根 Variance 方差 Stretch Vertically 该功能对于当某字段的数据变长时非常有用,选择它将使数据在大于规定的数据区时垂直向下延伸。 Suppress Repeated Values 此项功能可以显示或抑止显示重复数据。 Float As Band Stretches 选择了此功能,将使该字段内容在上条记录显示完整的情况下,接着显示本字段内容。 另外,报表生成器的环境记忆功能使得报表工作极为轻松。我们在设计报表的时候,打开的数据库文件、索引文件等环境信息在储存报表时,都被记忆。在使用报表时,我们只需用 Report Form < 报表文件名 > 即可,无需分别做打开数据库文件、打开索引文件等繁琐的工作。 4.举例 以下是一个更复杂的报表,它被用做财务费用帐页。 报表的设计除了遵从一定的原则外,同样采用一些技巧。尤其值得说明的是函数 fy 的定义(程序编制)。 我们知道,在设计财务帐目数据库时,每一笔帐结构均是类似的。所不同的是科目的不同,数值的不同等等。在报表设计的时候,有些科目和数值是无法事先确定的。如对于二级科目“公务费”,就有邮电费、维修费、取暖费等十几个三级科目,在报表中各三级科目的位置可预先确定,但 Detail 栏数值的位置就不好确定了。除非编制以下的函数程序,用 FY("XXX") 的形式调用, 在“邮电费”的数值栏填 FY("邮电费")、在“维修费”的数值栏填 FY("维修费"),...依次类推。 FUNCTION FY PARAMETER x IF km3=x &&判断三级科目与输入的名称是否相等 IF jfje=0 RETURN -dfje &&返回贷方金额的负值 ELSE RETURN jfje &&返回借方金额的值 ENDIF ELSE RETURN 0.00 &&若无此三级科目,返回零值 ENDIF 在本报表中还按月做了分组 Group ,目的在于财务的帐页上要求出现月计。 为满足满一页才打印输出的要求,可以编一程序计算要打印的帐目条数,当该条数等于或大于每页报表中的条数时就打印输出。计算及打印输出的程序为: ... * 恢复变量 lastpage 上次打印的最后页号 ... COUNT FOR km=mkm TO pagetol && 计算满足条件的帐目数 nowpr = pagetol-lastpage*pagenum&& pagenum 是每页报 && 表容纳的帐目数 nowpage=INT(nowpr/pagenum)&& 计算本次要打印的页数 pbpage=lastpage+1 pepage=lastpage+nowpage PRINTJOB REPORT FORM CW3 TO NOEJECT PRINTER OFF ENDPRINTERJOB lastpage=pepage ... * 保存变量 lastpage ... 四、关系范例查询 1.启动 在 Command 窗内打入以下命令 Modify Query < 文件名 >, 选择使用的数据库文件名(如果一个数据库已打开,就默认使用该数据库),即出现菜单生成器画面,同时系统菜单上出现 Query 项。 2.功能简介 Foxpro 2.5 的 RQBE(Relation Query-By-Example 关系范例查询)是使用户通过一相同的字段,十分方便地从多个数据库中提取所需要的信息,完成诸如查询、统计、汇总等一系列的工作。 事实上 RQBE 是通过使用嵌入 Foxpro 2. 5 中的 SQL 语言(结构化查询语言)中的 SELECT 命令来进行处理的。RQBE 是全菜单驱动的,通过填表、选择的方式完成查询工作。在对此查询方法感到满意存盘时,将自动地产生完成关于此查询工作的程序代码。此程序的扩展名为 QPR。当然,你可以在自己的应用程序中直接引用这一查询程序。 3.使用简介 屏幕上出现的查询窗口几乎包括了所有的内容,因而查询的工作几乎是填表的方式进行的。 当在多于一个数据库的几个数据库中查询信息时,就需要选择 Add , 这时出 现 Open file 对话框,在选择了相应的数据库后,RQBE Join Condition 对话窗出现,你应该使用该对话窗指定连接两个数据库的公共的字段。完成以上工作后,该数据库的文件名出现在 RQBE 窗口中的 Database 栏中。 Output Fields 是选择输出结果的字段。可以选取 Select Fields 按钮, 这时出现 RQBE Select Fields 对话框,在该对话框中可以非常容易地从各数据库中选择所要求的字段。 Order By是将查询的结果排序输出;Group By 是将查询的结果分组输出, 如果要使各分组列入结果之前满足某条件,就应选择 Having 项以输入该条件。 Output To 是选择查询结果的输出位置。可以将查询结果输出到 Browse (这是默认的位置),也可以到一个现有的报表或标签文件 Report/Label, 也可以到另一个数据库文件 Table/DBF,或者到一个临时文件 Cursor 中(在打开状态,该文件就象一数据库一样使用,当关闭该文件时文件就不存在了)。 在 Select Criteria(查询条件)区中,可以在 Field Name 的弹出式菜单中选择构成条件的字段,可选的运算有 Like (等于)、Exactly Like (完全等于)、More Than (大于)、Less Than(小于)、Between(介于两者间)和 In (包含于)。在多个条件的情况下,当各条件之间是 AND 的关系或本身带有 NOT 的情况,可以直接在查询区内表示;当各条件之间是 OR 的关系,可以选择 Insert 和 Remove 下的 Or 项,这时 Or 单独占条件的一行。 做完以上工作后就可以选择 Do Query 来看一下查询的结果,如果结果不满意或不符合查询要求,还可以再做相应的修改;你也可以选择 See SQL 来看一下系统自动生成的 Select 查询命令。在存盘时一个完成此查询工作的 PRG 程序文件自动产生,扩展名为 QPR。这时的查询工作可在 Foxpro 2.5 系统下直接用 Do <文件名.QPR> 来实现。 4.举例 在一学生成绩管理数据库系统中有以下基本数据库: 成绩库(CJ) 学号(XH) 课程号(KCH) 成绩(CJ) 930045 05 95 930023 05 89 920011 01 79 ... ... ... 学生库(JB) 学号(XH) 姓名(XM) 出生年月(CSNY) 班级(BJ) ... ... ... ... ... ... 92001 朱红 71.08.09 92机一 ... 930023 吕静 73.02.01 93化一 ... 930045 张晓华 73.09.18 93化一 ... ... ... ... ... ... 课程库(KC) 课程号(KCH) 课程(KC) 01 数学 02 英语 05 机械制图 ... ... 现在的问题: 在成绩库中选择打印出 93化一班、机械制图课的考试成绩表。 首先我们根据成绩表的要求的格式建立一个报表格式文件TRY.FRX (建立报表格式文件的方法详见报表生成器)。要求的格式如下: ┌─────────┐ │ ___班___课程 │ │ 考试成绩表 │ │ │ │姓名 成绩 │ │... ... │ │... ... │ │平均 ... │ └─────────┘ 然后, 在 Foxpro 2.5 的命令窗口(Command)中键入以下命令: USE CJ MODIFY QUERY TRY 其中 TRY 是人为的文件名。这时出现 RQBE 的驱动屏幕如下: System File Edit Database Record Program Window RQBE RQBE - TRY Databases Output Fields  Output To ┌─┐ ┌───┐ [X]Select Fields... ┌───┐ │CL│ │XH │ [ ]Order By... │Browse│ └─┘ │KCH │ [ ]Group By... └───┘ │CJ │ [ ]Having... []Options... └───┘ 《Do Query》 ──────────────────────────────────────── Field Name NOT Example Up=Lo Select ┌──────────────────────────┐Criteria │ │ │ │ └──────────────────────────┘< Or > 这时用空格键选择 Add , 分别添加 JB 和 KC 两数据库, 注意按系统提示分别填入两数据库的共有字段 CJ.XH、JB.XH和 CJ.KCH、KC.KCH, 连接符应选择 Exactly Like。选择完毕后在屏幕的左下方会出现以上两个对应的关系,见下图。 System File Edit Database Record Program Window RQBE RQBE - TRY Databases Output Fields Output To ┌─┐ ┌───┐ [X]Select Fields... ┌──────┐ │CL│ │CJ.CJ │ [ ]Order By... │Report/Label│ │JB│ │JB.XM │ [ ]Group By... └──────┘ │KC│ │JB.JB │ [ ]Having... []Options... └─┘ │KC.KC │ └───┘ ──────────────────────────────────────── Field Name NOT Example Up=Lo Select ┌──────────────────────────────┐ │CJ.XH [ ] Exactly L JB.XH [ ] │Criteria │CJ.KCH [ ] Exactly L KC.KCH [ ] │ │JB.BJ [ ] Exactly L "93化一" [ ] │ │KC.KC [ ] Exactly L "机械制图" [ ] │< Or > └──────────────────────────────┘ Criteria< Or > 在Output Fields窗口应选CJ. CJ 、 JB.XM、JB.BJ、KC.KC, 因为我们正是需要这些内容。 选择是通过激活 SelectFields... 检测窗来实现的。在 Out To 窗口中选 Report/Label。 接着激活 Option 检测窗, 分别写入 Report Format文件名TRY. FRX 和打印输出至 PRINTER。在屏幕的左下方填入待查询的条件,见图。注意 Example中的“93化一”和“机械制图”的引号""是系统自动加入的。至此,查询的结构就建立完毕。这时,只需选择 Do Query ,你就能从打印机上得到符合查询条件的学生成绩表。 你可以发现 RQBE 的工作过程竟如此的简单!!! 可以想象,如果用 FOXBASE 2.10 来实现上述的功能,对一个较熟练的程序员来说,恐怕也是一件相当费工费时的事情。 现在我们再看一看系统自动建立的查询程序语句。 选择See Query,即出现 TRY.QPR [READ ONLY] 程序窗口,程序如下: SELECT JB.XM,JB.BJ,KC.KC,CJ.CJ; FROM JB,KC,CJ; WHERE JB.XH=CJ.XH; AND CJ.KCH=KC.KCH; AND (JB.BJ == "93化一"; AND KC.KC == "机械制图"); INTO CURSOR QUERY REPORT FORM TRY.FRX TO PRINTER 我们不难将以上的程序语句移入我们自行开发的系统中,如果再运用宏代换,即可在程序中方便地实现各种查询的操作了。 五、编制在线帮助 1.简介 作为应用系统的设计开发,除了要达到功能完备的要求以外,界面友好是当今系统设计又一重要的要求课题。对于 DOS 系统的数据库应用系统来说, 除了在系统中使用下拉式菜单、弹出式菜单等菜单系统外,还应考虑制作相应的帮助系统。该帮助系统应包括系统设计开发的信息、该系统的使用简介、以及最重要的相应内容敏感帮助系统(即:如 F1 为求助热键,当按下它时,立即显示与当前程序运行环境有关的帮助提示信息)。 Foxpro 2.5 可以使你非常方便地制作类似的帮助系统。 2.使用简介 首先应建立一个帮助系统数据库,该数据库由一个字符型字段和一个备注型字段构成,字符型字段用以存放帮助的项目名,备注型字段用以存放相应的帮助信息。 当然该数据库应包含尽可能多的帮助信息。 帮助数据库建立完毕后,就可以用 set help to <帮助数据库文件名> 命令关闭当前使用的帮助数据库,打开你命名的帮助数据库。 在制作内容敏感帮助系统的时候用 set topic to <表达式>。 这样, 在按了F1 帮助热键后屏幕上显示的不是待选的各帮助项目名,而是与 <表达式> 有关的项目的明细帮助信息。 3.举例 ┌───┐ │主菜单│ └───┘ │ ┌───┬────┴──────┬───┐ │ │ │ │ ┌─┐ ┌─┐ ┌─┐ ┌─┐ │输│ │修│ │查│ │退│ │ │ │ │ │ │ │ │ │入│ │改│ │询│ │出│ └─┘ └─┘ └─┘ └─┘ │ │ │ ┌─┐ ┌─┐ ┌─┐ │模│ │模│ │模│ │块│ │块│ │块│ │m1│ │m2│ │m3│ └─┘ └─┘ └─┘ 我们建立帮助数据库 myhelp.dbf , 该数据库有两个字段:XM (字符型)和MX (备注型),数据库的内容见表下。 xm mx ──────────────────────────────── 关于本系统 本系统的开发者: 开发日期: 在本系统开发的过程中得到了档案科同志们的大力 协助,在此一并致谢。希望本系统的用户对本系统 的使用和交流,提出宝贵的意见和建议。 输入输入各项数据时请注意数据的准确性,特别是 经历一栏,请将输入方式置为全角输状态。 修改...... ...... 查询...... ...... 数据库建立完毕后,在应用系统的主控模块的开始处加入命令:set help tomyhelp ,在 m1 模块中的起始处加入 set help to "输入",在 m2 模块中的起始处加入 set help to "修改",在 m3 模块中的起始处加入 set help to "查询" ,这样,一个简单的具有内容敏感的帮助系统就做好了。