520 likes | 743 Views
第四章 程序设计初步. 第一节 程序文件 第二节 程序的控制结构 第三节 多模块程序 第四节 窗口设计样例. 4.1 程序文件. VFP 程序设计包括结构化程序设计和面向对象程序设 计,但结构化程序设计仍是面向对象程序设计的基础。 4.1.1 程序文件的建立与执行 一、程序文件的建立与修改 MODIFY COMMAND < 文件名 >. 文件名由用户指定,扩展名为 .PRG. 程序文件由 VFP 命令组成. 4.1.1 程序文件的建立与执行. 文件的退出与保存 Ctrl+W: 文件存盘推出 ESC : 若程序文件修改过,将询问“放弃修改吗?”
E N D
第四章 程序设计初步 第一节 程序文件 第二节 程序的控制结构 第三节 多模块程序 第四节 窗口设计样例
4.1 程序文件 VFP程序设计包括结构化程序设计和面向对象程序设 计,但结构化程序设计仍是面向对象程序设计的基础。 4.1.1 程序文件的建立与执行 一、程序文件的建立与修改 MODIFY COMMAND <文件名> 文件名由用户指定,扩展名为.PRG 程序文件由VFP命令组成
4.1.1 程序文件的建立与执行 文件的退出与保存 Ctrl+W:文件存盘推出 ESC:若程序文件修改过,将询问“放弃修改吗?” 双击左上角控制菜单:将询问“将所做的更改保存到*.prg吗?” 单双击右上角关闭按钮:将询问“将所做的更改保存到*.prg吗?” “文件”菜单:“保存”、“另存为”或“还原”命令 二、程序的执行 DO <文件名> 例如:DO MCZZ.QPR &&运行查询程序 默认扩展名为.PRG,若为其它类型必须指明扩展名
4.1.1 程序文件的建立与执行 举例 例4-3:设计程序创建数据库SBSJ{SB,BMDM,DX,ZZ} creat data sbsj add tabl sb add tabl zz add tabl dx add tabl bmdm close data
4.1.1 程序文件的建立与执行 三、程序的书写规则 1、命令分行 一行只写一条命令,结尾回车 一行写不完,则加续行号“;”回车 2、命令注释 注释行以“*”号开头 一条命令后可加“&&”引出注释 例如: *本程序修改指定记录 SET DATE USA &&日期格式为MM-DD-YY
4.1.2 程序文件中的专用命令 一、程序结尾的专用命令 RETURN:使程序结束,返回到上级或命令窗口,准许缺省 CANCEL:正常终止,清除程序私有变量,返回到命令窗口 QUIT:退出VFP系统,自动删去临时文件,返回WINDOWS 二、定位输入输出专用命令 @<行,列> [SAY <表达式1>] [GET <变量名>] [DEFAULT <表达式2 >] 输入及编辑数据 数据在窗口显示位置 输出数据 指定变量初值
[P128 例4-1] CLEAR && 清屏幕 USE sb jlh=1 && GET 变量必须赋初值 @2,10 SAY "请输入记录号:" GET jlh READ GO jlh @4,10 SAY "请修改第"+STR(jlh,1)+"个设备的数据" * 输出提示字符串 @6,10 SAY "价格" GET 价格 *价格是字段变量,已经有初值 @8,10 SAY "部门" GET 部门 READ USE
三、WAIT命令 暂停程序的运行,直到用户输入一个字符,也可用于输出一条提示信息 WAIT [<信息文本>] [TO <内存变量>] [WINDOW [AT <行>,<列>]] [NOWAIT] [CLEAR] [NOCLEAR] [TIMEOUT <数值表达式>] 保存键入的字符,省略TO子句不保存 省略则显示“按任意键继续…. TIMEOUT子句设定等待时间(以秒为单位) 不等待用户输入 关闭提示窗口 不关闭提示窗口,直到下一个WAIT命令自动关闭 WINDOW子句使屏幕出现一个WAIT提示窗口, 内容由<信息文本>确定, 位置有AT子句指定.省略AT子句则出现在屏幕右上角
4.2 程序的控制结构 顺序结构:按命令的书写顺序依次执行 分支结构:根据指定条件的当前值在两条 基本结构 或多条路径中选择一条执行 循环结构:由指定条件的当前值来控制循 环体中的语句(或命令)序列 是否要重复执行。 4.2.1 分支结构 VFP可用条件语句或分支语句实现分支结构
一、简单的条件语句 IF <逻辑表达式> <语句序列> ENDIF [P130 例4-3] USE sb LOCATE FOR NOT 主要设备 IF FOUND() && 若查到,FOUND函数返回.T. DISPLAY 名称,价格 REPLACE 价格 WITH 价格*(1-0.1) DISPLAY 名称,价格 ENDIF USE RETURN
二、带ELSE的条件语句 IF <逻辑表达式> <语句序列1> ELSE <语句序列2> ENDIF
三、宏替换函数 函数格式: &<字符型内存变量>[.<字符表达式>] 功能:替换出字符型内存变量的值 [P131 例4-4] m=5 x="m" ? x &&显示m ? &x &&显示5 若宏替换函数后还有非空的<字符表达式>,则需要在此<字符表达式>前加“.”。
[P131 例4-5] clear @5,10 SAY "请输入表名:" GET bm DEFAULT SPACE(10) READ bm=ALLTRIM(bm) &&删去两端的空格 IF FILE("&bm..dbf") && &bm后用一个.来连接.dbf use &bm browse ELSE WAIT "该文件不存在,按任意键退出" WINDOW ENDIF
三、多分支语句 DO CASE CASE <逻辑表达式1> <语句序列1> CASE <逻辑表达式2> <语句序列2> …………… CASE <逻辑表达式n> <语句序列n> [OTHERWISE <语句序列n+1>] ENDCASE
[P132 例4-6] clear yue=month(date()) &&获取月份 do case case inlist(yue,3,4,5) jj="春" case inlist(yue,6,7,8) jj="夏" case inlist(yue,9,10,11) jj="秋" case inlist(yue,12,1,2) jj="冬" endcase wait jj window at 8,30 &&当前季节显示在WAIT窗口
4.2.2 循环结构 循环条件 一、条件循环 DO WHILE <逻辑表达式> <语句序列> ENDDO [P133 例4-7] use sb do while not eof() if 价格>10000 ? 名称 endif skip enddo use 循环体
[P134 例4-8] store 0 to k1,k2,k3 use sb do while not eof() do case case 价格>90000 k1=k1+1 case 价格<10000 k3=k3+1 otherwise k2=k2+1 endcase skip enddo ?"9万元以上设备个数:"+str(k1) ?"1~9万元设备个数 :"+str(k2) ?"1万元以下设备个数:"+str(k3) use
二、步长循环 FOR <内存变量>=<数值表达式1> TO <数值表达式2 > [STEP <数值表达式3 >] <语句序列> ENDFOR|NEXT [P135 例4-9] s=0 for i=1 to 100 s=s+i next ?"s=",s 终值 步长,默认为1 初值
三、扫描循环 SCAN [<范围>] [FOR <逻辑表达式1>] [WHILE <逻辑表达式2 >] <语句序列> ENDSCAN 在<范围>内依此寻找满足FOR条件或WHILE条件的记录,并对找到的记录执行<语句序列> [P135 例4-10] use sb scan for 价格>10000 ? 名称 endscan use
四、循环辅助语句 LOOP:使执行转向循环语句的头部继续循环 DO WHILE <逻辑表达式> …… LOOP …… ENDDO EXIT:立即退出循环,转去执行循环外的语句 DO WHILE <逻辑表达式> …… EXIT …… ENDDO
[P136 例4-11] store 0 to i,s,t do while i<100 i=i+1 s=s+i if int(i/2)=i/2 loop endif t=t+i enddo ?"1+2+3+...+100=",s ?"1~100奇数和为",t
五、多重循环 循环体内包含其它循环→循环嵌套 clear use sb @5,10 say "请输入价格:" get jg default 0 read scan &&外循环 if 价格<jg ?编号+space(3)+名称+space(3)+str(价格,9,2) ? &&换行 for i=1 to 30 &&内循环 ??"-" endfor endif endscan use
4.3 多模块程序 模块是可以命名的一个程序段,可指主程序、子程序和自定义函数 4.3.1 子程序 一、调用与返回 两个具有调用关系的程序文件,称调用程序为主程序,被调用程序为子程序 主程序遇到DO命令,转向子程序执行,称为调用程子程序。 子程序执行到RETURN语句(或缺省该语句),返回到主程序中的DO命令的下一个语句执行,称为返回主程序
二、带参数子程序的调用和返回 DO <程序名1> [WITH <参数表>] [IN <程序名2 >] 相对应的在子程序中,用PARAMETERS来接收和回送参数。 PARAMETERS <参数表> 可以是表达方式,内存变量必须赋初值 当<程序名1>是<程序名2>中的一个过程时,必须指明 1、该语句应为子程序的第一条命令, 2、PARAMETERS参数应与WITH参数表一一对应
三、子程序嵌套 子程序还可以调用其它子程序(嵌套),因嵌套引出多两种返回方式 RETURN [TO MASTER|TO <程序名>] 任何时候要推出VFP,只要执行QUIT命令 强制返回指定程序 返回最外层主程序 省略,返回外层调用程序
4.3.2自定义函数 一、自定义函数的建立 [FUNCTION <函数名>] [PATAMETERS <参数表>] <语句序列> [RETURN <表达式>] 使用它表示该函数包含在调用程序中,缺省则函数为一个独立文件 函数体 用于返回表达式的函数值,省略则返回.T. 自定义函数不能和系统函数、内存变量同名,使用方法与系统函数相同
[P139 例4-14] 解法二 *例4-14解法二 clear @5,10 say "一次项系数:" get a default 1 @7,10 say "常 数 项:" get b default 0 read ?"x:",root(a,b) function root parameters u,v return iif(u=0,"无解",-v/u) IIF系统函数,若u=0,值为“无解”;否则为-v/u
二、数组参数的传递 发送参数数组前加@,接收参数数组不需定义。 *例4-14数组传送,P140 clear dimension fs(2) fs(1)=1 fs(2)=0 @5,10 say "一次项系数:" get fs(1) @7,10 say "常 数 项:" get fs(2) read ?"x:",root(@fs) &&树组前加@可传递数组 function root parameters js && js(1)=fs(1),js(2)=fs(2) return iif(js(1)=0,"无解",-js(2)/js(1))
4.3.3过程 VFP准许一个.PRG文件中设置多个程序模块,除主程序以外每个模块为一个过程 过程的格式如下: PROCEDURE <过程名> [PARAMETERS <参数表>] <命令序列> [RETURN] 过程部分往往位于程序文件的最后.
[P141 例4-15] set decimals to 2 &&设置小数点后保留两位 ymj=0 @5,10 say "请输入半径:" get bj default 0 read do js with bj,ymj ?"ymj=",ymj return procedure js parameters r,s s=pi()*r*r return
过程文件 主程序文件 ymj=0 @5,10 say "请输入半径:" get bj default 0 read do js with bj,ymj in js1 &&调用过程文件js1中的过程js ?"ymj=",ymj return 过程文件 procedure js parameters r,s s=pi()*r*r return
4.3.4变量的作用域 以变量的作用域来分,内存变量分为:公共变量、私有变量和本地变量 一、公共变量 公共变量是在一个程序中的任何模块都可以使用的变量,建立命令格式 PUBLIC <公共变量表> • 需定义为公共变量的变量:下层模块建立的变量要供上层使用,某模块建立的变量要供并列模块使用 • VFP命令窗口定义的变量均为公共变量,公共变量必须用命令(RELEASE或CLEAR)来清除 建立的同时, 赋初值为.F.
二、私有变量 • 私有变量仅在定义它的模块及其下层模块中使用,定 义它的模块运行结束自动清除 • 私有变量准许与上层模块的变量同名,同名时屏蔽上 层模块的变量.本模块运行结束再恢复上层模块变量 私有变量类型声明格式如下: PRIVATE [<内存变量表>] [ALL [LIKE|EXCEPT <通配符>]] 注意: (1)PARAMETERS声明的参变量也是私有变量 (2)PUBLIC命令除声明明变量类型外还赋初值,称为建立;PRIVATE只是声明而已,不进行赋值。
[P142 例4-17] parameters sj private mj mj=3.14*sj*sj ?"程序执行时的变量清单" list memo like ?j return 在命令窗口输入: mj=0 bj=3 do e4_17 with bj 观察输出情况,解释
三、本地变量 本地变量只能在建立它的模块使用,该模块运行结束自动清除 命令格式: LOCAL <内存变量表> 注意:LOCAL不可缩写 例E4_bl <内存变量表>指定的变量为本地变量,并赋初值.F.
4.3.5程序调试方法 一.调试的概念 程序调试的目的:检查并纠正程序中的错误,以保证 程序正确、可靠地运行。 程序调试的步骤:检查程序是否存在错误 确定出错位置 纠正错误 1、程序中常见的错误 (1)语法错误,例:数据类型不匹配等 (2)超出系统准许范围错误,例:文件太大等 (3)逻辑错误,例:计算逻辑错误等
2、查错技术 查错技术一:静态检查,通过阅读程序,找出错误 查错技术二:动态检查,通过执行程序考察程序是否有错 (1)设置断点 在断点处查看中间结果,考察程序是否有错 (2)单步执行 一次执行一个命令,相当于断点设在每条指令之后 (3)跟踪 在程序执行过程中,跟踪某些信息的变化,以确定程序序是 否有错 (4)设置错误陷阱 通过错误陷阱捕捉可能发生的错误。可通过ON ERROR语句设 置陷阱
4.3.6 结构化程序设计 [P147 例4-19] 结构化设计的三种方法 (1)自顶向下,逐步求精 从整体出发,逐层分解,使复杂的问题简单化 (2)模块化 将系统分解为若干功能相关而又相对独立的模块 (3)层次化 系统按层次结构布局,即以树型结构来组织系统的全部模块
4.4 窗口设计样例 4.4.1 浏览窗口的定制 VFP准许用户按照自己的需要配置浏览窗口的功能。 一、BROWSE命令 BROWSE [FIELDS <字段表>] [FONT <字符表达式1>[,<数值表达式1>]] [STYLE <字符表达式2>] 见下页解释 字体形状:B,I,U 字体:宋,楷 字体大小:16,20
表达式1为检验条件,光标离开字段时检验 设置字段级有效性检验 <字段表> 只读 栏宽 <字段名>[:R][:<数值表达式>][:V=<表达式1>[:F][:E=<字符表达式1>]] [:P=<字符表达式2>][:B=<表达式2>,<表达式3>[:F]] [:H=<字符表达式3>][:W=<逻辑表达式1>] 不管字段是否修改均检验,省略,则只修改时才检验 不管字段是否修改均检验,省略,则只修改时才检验 检验出错提示信息 格式代码列表,见P111-112 下界 范围检查 上界 栏目名,默认字段名为栏目名 为真,准许进入该字段,否则越过
BROWSE命令 记录指针移到首记录 光标只能在指定字段移动 记录指针保持原位置 保存浏览窗口外观 [FOR <逻辑表达式> [REST] [FREEZE <字段>] [LAST] [LOCK <数值表达式2>] [LPARTITION] [NAME <对象名>] 光标在左分区第一字段, 准许使用表格控件的对象 保持某些字段保持显示 LOCK使浏览窗口一分为二,右分区按常规显示左分区显示表的前N个字段
BROWSE命令 删除左分区网格线 [NOAPPEND] [NODELETE] [NOEDIT|NOMODIFY] [NOLGRID] [NORGRID] [NOLINK] [NOMENU] [NOREFRESH] [NORMAL] [NOWAIT] 不准许编辑,但准许删除和添加 不准许追加记录 不准许做删除标记 删除右分区网格线 使系统菜单不出现表菜单 用默认配置打开浏览窗口 打开窗口继续运行程序 禁止刷新浏览窗口 取消左、右分区显示按记录联动
等待输入时间,超过浏览窗口自动关闭 BROWSE命令 保持浏览窗口为活动,操作其它窗口后即返回 设置浏览窗口标题 [SAVE] [TIMEOUT <数值表达式3>] [TITLE <字符表达式3>] [VALID[:F] <逻辑表达式2> [ERROR <字符表达式4>]] 设置光标离开校验: 记录修改后光标离开后计算<逻辑表达式2> ,其值为真准许光标离开 <字符表达式4>为出错提示信息
BROWSE命令 为真准许修改记录,否则为只读 浏览窗口每个字段宽度,但操作时可变 [WHEN <逻辑表达式3>] [WIDTH <数值表达式4>] [WINDOW <窗口名1>] [IN [WINDOW] <窗口名2>|IN SCREEN] 指定一个用户定义的窗口,浏览窗口采用其特性 窗口名2指定浏览窗口的父窗口,SCREEN表示父窗口为VFP主窗口
[P151 例4-20] clear all select 0 use bmdm index on 代码 tag dm select 0 use sb browse title "设 备 价 格 表" nodelete lock 1 nomenu; fields 编号:R,名称:R:H="设备名称",价格:B=2001,500000:F:W=bmm() function bmm select bmdm seek sb.部门 wait 名称 window nowait &&WAIT提示窗口显示部门名 select sb
二、定义功能键 功能键可以是单键、组合键或鼠标按键,当用户使用定 义的功能键将执行预定的功能 ON KEY [LABEL <键标号>] [<命令>] 注释: (1)当程序执行(READ、BROWSE)等命令,进入某种暂 停状态,用户即可使用功能键执行规定的命令。 (2)PUSH KEY 保存 POP KEY 恢复 PUSK KEY CLEAR:清除 定义的功能键,见P357附录二 一般为DO命令
[P153 例4-22] CLEAR ALL PUSH KEY CLEAR &&清除以前设置的功能键 ON KEY LABEL rightmouse DO tis &&设置鼠标右键为功能键 select 0 use bmdm select 0 use sb browse title "设备表" &&编辑sb.DBF push key clear
[P153 例4-22]续 procedure tis if varread()="部门" &&当前字段为部门时返回.T. select bmdm browse title "部门表" nomodify &&显示部门代码和名称 =inkey(0,"MH") &&等待击键 select sb endif
4.4.1 窗口命令与函数 一、窗口命令 P154表4-1列出了VFP部分常用窗口命令的名称和简要功能。 1、窗口激活命令 ACTIVATE WINDOW [<窗口名1>[,<窗口名2>…]] <窗口名1>[,<窗口名2>…]要激活的窗口的名称 下面两条指令先后激活计算器和文本编辑窗口 ACTIVATE WINDOW calculator &&激活计算器 MODI COMM wj.txt
2、窗口关闭命令 将窗口从屏幕清除,并且删除它在内存中的定义 (1)RELEASE WINDOWS [<窗口名表>] 关闭在<窗口名表>中指定的用户定义窗口和VFP系统窗口,缺省关闭活动的用户定义窗口 (2)CLEAR WINDOWS 关闭所有用户定义的窗口 (3)CLEAR ALL 关闭所有用户定义的窗口,并返回到系统初始状态