第七章 程序设计基础

48
第第第 第第第 第第第第第第 第第第第第第

Upload: reagan-gutierrez

Post on 01-Jan-2016

141 views

Category:

Documents


0 download

DESCRIPTION

第七章 程序设计基础. 5.1.1 VFP6 程序设计基本概念. VFP6 支持过程化程序设计和面向对象程序设计两种程序设计与开发的类型。 下面是一个完整的 VFP 过程化程序,可以引出几个基本概念。. * 功能说明:求圆形的面积。 *文件名: L501.PRG CLEAR CTALK=SET("TALK") SET TALK OFF INPUT " 请输入圆的半径,半径 =" TO R S=PI()*R*R ? " 半径为 "+ALLTRIM(STR(R))+" 的圆,面积 =",S SET TALK &CTALK RETURN. - PowerPoint PPT Presentation

TRANSCRIPT

第七章第七章

程序设计基础程序设计基础

5.1.1 VFP65.1.1 VFP6 程序设计基本概念程序设计基本概念 VFP6 支持过程化程序设计和面向对象程序设计两种程序设计与开发的类型。 下面是一个完整的 VFP 过程化程序,可以引出几个基本概念。

* 功能说明:求圆形的面积。* 文件名: L501.PRGCLEARCTALK=SET("TALK")SET TALK OFFINPUT " 请输入圆的半径,半径 =" TO RS=PI()*R*R? " 半径为 "+ALLTRIM(STR(R))+" 的圆,面积 =",SSET TALK &CTALKRETURN

1 、从形式上看, VFP 的程序是由若干有序的命令行组成,且满足下列规则:( 1 )一个命令行内只能写一条命令,命令行的长度不得超过 2048 个字符,命令行以回车键结束。( 2 )、一个命令行可以由若干个物理行组成,即一条命令在一个物理行内写不下时,可以分成几行。换行的方法有两种:一种是在物理行的末尾加符号“ ;” ,表示下一行输入的内容是本行的继续;另一种是系统自动换行,即输入程序时,只管逐条命令输入,无需考虑本条语句是否超过屏幕行宽的最大限度,当输入的语句超过屏幕的最大行宽时,系统自动换行。输入时只需在一行结束时按回车键,通知系统本命令行输入完毕。( 3 )为便于阅读,可以按一定的格式输入程序,即一般程序结构左对齐,而控制结构内的语句序列比控制结构的语句缩进若干格。2 、从功能上看,程序可以分为三个部分:第一部分是程序的说明部分,在本例程序中是前面的四行,一

般用于说明程序的功能、文件名等需要说明的有关信息。第二部分是进行数据处理的部分,在本例程序中是从第五行开始的三行。通常任何一个有意义的程序,总是要有一些原始数据,否则,这个程序就没有处理对象。同样,程序运行的结果也有必要显示或打印出来,否则,用户将不知道程序干了一些什么。因此,第二部分程序常包括下列三个部分,依次为:提供原始数据部分、数据处理部分、输出结果部分。第三部分是程序的控制返回部分,在本例中就是最后二条命令。它控制程序返回到调用该程序的调用处。

过程化程序设计与面向对象程序设计 过程化程序设计:它是采用结构化编程语句来编写的程序。这类方法的特点是容易把一个复杂的程序分解为若干个较小的过程,每个过程都可进行独立的调试。这类设计方法发展的总思想是从程序员角度考虑使程序设计更简单,而较少从使用角度去考虑。使用这类方法设计的程序流程完全由程序员控制,使用者只能做由程序员预先安排好的事情。

面向对象程序设计:这类程序设计思想是面向对象,即设计的重要任务在于描述对象。程序是由事件驱动的,因而,在执行过程中,持续等待的是一个发生在对象上的事件。而发生什么事件则要看使用者的操作,如单击、双击鼠标等。至于下一步的程序流向,则要看驱动的是什么事件。这类程序设计的主要目的是从任何方便与简化使用入手,由使用者控制程序流向,这在一定程序上增加了编程的难度。

5.1.2 VFP65.1.2 VFP6 程序设计基本操作程序设计基本操作

1 、过程化程序设计基本操作 ( 1 )建立过程文件。在 VFP 中,一个过程文件就是一个 ASCII 文本文件,因而可用各类编辑工具来建立。在 VFP 中有下面二种简易方法来建立: ■在【文件】菜单下的【新建】菜单项中,选择“程序”可选项 。■在命令窗口中使用 MODIFY COMMAND 命令。

返 回

格式: MODIFY COMMAND [< 文件名 >/ ? ]

功能:打开文本编辑窗口,编写程序代码。参数描述:[< 文件名 >] :为可选项,指定打开或创建的程序文件名。若不指定新建程序文件的扩展名, VFP 自动指定 .PRG 为扩展名。MODIFY COMMAND 命令支持含有“ *” 和“?”通配符的文件梗概。名称与这个梗概匹配的每一个文件都在编辑窗口中打开。若省略文件名,将给打开的编辑窗口赋一个初始名称“程序 1.PRG” 。当关闭编辑窗口时,可以用另外的文件名保存该文件。[ ? ] :显示“打开”对话框。可以从中选择一个已有程序或输入要创建的新程序名。说明: 修改程序文件之后,更新过的文件将写到磁盘上。除非在配置文件中用 TEDIT指定一个外部编辑器,否则,一般使用 VFP的内置编辑器。

【例 5-2】用户通过 VFP6 的命令窗口建立上例程序文件。在 VFP6 的命令窗口中输入下条命令后按回车键。MODIFY COMMAND L501

打开程序编辑窗口

在程序编辑窗口中输入程序代码

用 Ctrl+W存盘退出编辑窗口,或单击程序编辑窗口上的【关闭】按钮,在弹出的对话窗口中确定存盘,生成L501.prg 文件。

( 2 )运行程序 下面的任一方法均可运行程序:■选择【程序】菜单下的“运行”菜单,利用“运行”对话框选择要运行的程序;■在命令窗口中输入如下命令:

DO < 程序文件名 >

系统就会运行这个程序。如果文件不加扩展名,系统会假定它具有 .PRG 的扩展名,如果想运行一个具有其它扩展名的命令文件时,在输入命令时必须给出这个命令文件的全名。如:要运行上例中编辑的程序,可以在命令窗口中输入: DO L501然后按回车键执行。

5.1.3 VFP5.1.3 VFP 程序设计编程方式程序设计编程方式 VFP 程序由代码组成,代码包括以命令形式出现的指令、函数和 VFP 可以理解的任何操作。这些指令包含在“命令”窗口、程序文件、表单设计器与类设计器的事件或方法程序代码窗口、菜单设计器的过程代码窗口、报表设计器的过程代码窗口中。

使用“命令”窗口 可以在“命令”窗口中键入 VFP 命令并按 Enter 键执行。若要重新执行该命令,还可以将光标移到此命令所在行并按 Enter 键。 甚至可以在“命令”窗口中像独立程序一样执行多行代码。要在“命令”窗口中运行多行代码,可以按下述方法执行: ( 1 )选取代码行。 ( 2 )按 Enter 键或右击并在快捷菜单中选择“运行所选区域”。因为“命令”窗口是一个编辑窗口,所以在编辑命令时可以使用VFP 提供的编辑工具。在“命令”窗口中可以修改、插入、删除、剪切、复制和粘贴正文。

在“命令”窗口中执行命令的优点是:能够立即执行被键入的命令,不需要将其保存为文件并用程序方式执行。此外,在菜单或对话框中所作的选择可以马上转换成“命令”窗口中的命令。用户可以将这些命令复制并粘贴到 VFP 程序中,然后重复执行这些程序。这样做可以很容易地重复执行成百上千条的命令。

2 、创建程序VFP 程序是包含一系列命令的文本文件。在 VFP 中可以通过下述途径创建程序:( 1 )在项目管理器中,选定“代码”选项卡中的“程序”项;( 2 )选择“新建”命令。或者:( 1 )在【文件】菜单中选择【新建】命令;( 2 )在“新建”对话框中选择“程序”;( 3 )单击【新建文件】按钮。或者在“命令”窗口中键入:MODIFY COMMAND

3 、保存程序创建程序后,一定要注意保存程序。若要保存程序,可以从【文件】菜单中选择【保存】命令。或者按 Ctrl+W 组合键保存,若不想保存对新建程序或已有程序所做的修改,也可以使用 Ctrl+Q组合键,不存盘而退出编辑窗口。若要关闭一个没有保存的程序,则会弹出相应对话框,提示用户是否保存已作的修改。若保存了一个由项目管理器创建的程序,则该程序被加入到项目中。若保存一个尚未命名的程序,则会打开“另存为…”对话框,提示用户可以在其中为程序指定程序名。程序保存后,可以运行或修改它。

4 、修改程序程序保存后可以修改。首先,按以下四种方法之一打开想要修改的程序文件:■若程序包含在一个项目中,则在项目管理器中选定它并选择

修改命令。 ■在【文件】菜单中选择【打开】命令,这时弹出一个包含文件列表的对话框,在“文件类型”列表框中选择“程序”,然后在文件列表中选定要修改的程序,单击【确定】按钮。 ■在“命令”窗口中按如下方式键入要修改的程序名:

MODIFY COMMAND < 程序文件名 >

■在“命令”窗口中输入: MODIFY COMMAND ?

然后从文件列表中选择要修改的程序,单击【打开】按钮。打开文件之后便可进行修改,修改完成后就可以保存。

5 、运行程序程序创建之后便可以运行。若要运行程序,有以下三种方法:■若程序包含在一个项目中,则可在项目管理器中选定它,并选择【运行】命令。

5.2 VFP65.2 VFP6 的程序设计语言基础 的程序设计语言基础

5.2.1 VFP 的交互式输入输出命令

5.2.2 VFP6 程序设计的条件与循环

返 回 退 出退 出

5.2.1 VFP5.2.1 VFP 的交互式输入输出命令 的交互式输入输出命令 设计程序,就是用一系列命令存储数据并操作这些数据。程序设计的原材料是数据和数据的存储容器,而处理这些原材料的工具是命令、函数的操作符。

1 、交互式输入命令( 1 )字符接收语句 格式: ACCEPT [< 提示信息 >] TO < 内存变量名 >

功能:将从键盘上接收的字符串数据存入指定的内存变量中。提供此命令是为了向后兼容,在 VFP 中可以用文本框控制命令代替。参数描述:[< 提示信息 >] :指定提示信息字符串,其后是数据输入区。在VFP 中,提示文本的字体与 VFP主窗口的字体相同。但输入的字符数据用 9磅 FoxFont 字体显示。

[< 内存变量名 >] :指定存储字符数据的内存变量或数组元素。如果没有定义此内存变量, ACCEPT 将自动创建。如果没有输入数据就按 Enter 键,内存变量或数组元素则为空字符串。 说明:在 VFP 中可用表单设计器或 DEFINE CLASS 来创建文本框控制。ACCEPT 命令允许直接向内存变量或数组元素输入字符数据,输入时不需要用引号将字符括起来。 执行此语句时,先在屏幕上显示 < 提示信息 > ,光标紧随其后,然后暂停程序运行,等待用户从键盘上输入信息。输入的信息可以是任何可显示的 ASCII码字符串,并以回车键结束。系统将此字符串信息存入指定的内存变量中,然后,继续运行暂停的程序。【例 5-3】试编程完成下述功能:从键盘随机输入某个表的文件名,要求打开并显示此表的内容。在命令窗口输入下列命令:MODIFY COMMAND L503 ( 文件名中的扩展名 .PRG 可省略,以后不再说明 )

屏幕显示编辑窗口。在编辑窗口输入如下程序代码后用 Ctrl+ W存盘,返回命令窗口。

CLEARSET TALK OFFACCEPT " 请输入表文件名 " TO FileNameUSE (FileName)LISTUSERETURN

说明:程序中第四句使用了宏代换函数,这是由于 FileName本身不是文件名,而其内容才是文件名。 ( 2 )通用数据接收命令 ACCEPT 语句只能给字符型内存变量提供数据。如果用户想给其它类型的内存变量提供数据,可以使用下列命令:

格式: INPUT[< 提示信息 >] TO < 内存变量名 >

功能:用于接收从键盘上输入的表达式,并将计算结果存入指定的内存变量或数组元素中。包含此命令也是为了提供向后的兼容性。在 VFP 中,该命令也可以用文本框控制代替。参数描述:[< 提示信息 >] :提示信息,提示用户输入数据。[< 内存变量名 >] :指定一个内存变量或数组元素,存储从键盘输入的数据。如果指定的内存变量或数组元素不存在, VFP 将自动创建该内存变量或数组。说明:INPUT 语句与 ACCEPT 语句的执行过程相同,功能相似。< 内存变量名 > 的数据类型取决于输入数据的类型。可以为数字型、字符型、日期型和逻辑型。 INPUT 语句与 ACCEPT 语句的区别是: ACCEPT 命令只能接收字符串,而 INPUT 语句可以接收任意类型的 VFP 表达式;如果输入的是字符串, ACCEPT 语句不要使用字符型定界符,而 INPUT 语句必须用定界符括起来。

【例 5-4】试编程完成下列功能。从键盘上随机输入一个正数,以此数为半径,求圆面积和球体积,并输出结果。程序如下:

*L504.PRGCLEARCTALK=SET("TALK")SET TALK OFFINPUT " 半径 =" TO RS=PI()*R*RV=4/3*PI()*R**3? " 圆面积 =",S? "球体积 =",VSET TALK &CTALKRETURN

程序中的第一行为注释行,说明此程序文件名;第四行的功能是不显示命令处理信息,第十行的功能是恢复显示命令处理信息。 在命令窗口中执行:DO L504

屏幕显示半径 =

输入 10 后按 Enter键

10显示结果

圆面积 = 314.16球体积 = 4188.790205

( 3 )输入一个字符语句格式: WAIT [ < 提示信息 > ] [TO < 内存变量名>]功能:暂停正在运行的程序,直到输入一个字符为止。此语句与 ACCEPT 语句的功能部分相似。若选择 TO < 内存变量名 >子句,则将输入的单个字符存入指定的内存变量。若直接输入回车键,则内存变量中存入空字符串。内存变量的类型为字符型。若选择 < 提示信息 >子句,执行此命令时,屏幕上将显示提示信息,否则,屏幕上将显示“按任意键继续…”WAIT 语句主要用于下列两种情况。■暂停程序的运行,以便观察程序的运行情况,检查程序运行的中间结果。 ■根据实际情况输入某个字符,以控制程序的执行流程。比如,在某应用程序的“ Y/ N”选择中,常用此命令暂停程序的执行,等待用户回答“ Y” 或“ N” ,由于这时只需输入单个字符,也不用按回车键,操作简便,响应迅速。

2 、格式化输出命令 前面的章节中在屏幕上显示信息时,使用的是非格式化输出命令:“ ?” 或“ ??” ,为了能按一定的要求来设计屏幕格式,使之美观、方便,下面介绍一个屏幕显示格式控制命令。 格式: @ < 行号 , 列号 > SAY < 表达式 >

功能:从指定的行、列号开始输出表达式的值。说明:① < 表达式 > 可以是常数、字段变量及由它们组成的表达式。②定位输出时,一次只能输出一个表达式。

3 、程序设计辅助命令( 1 )、中止程序运行■在程序运行过程中,按 Esc 键可以中止程序的运行,系统会显示警告对话框让用户选择:【取消】 中止程序运行,这是缺省选择;【挂起】 暂停程序运行,返回命令窗口。当选择【程序】菜单下的【继续执行】选项或在命令窗口中输入“ Resume” 命令,系统

则从中止的地方继续程序的执行;【忽略】 忽略所给的 Esc ,继续程序的执行。通常在程序的开始时加有命令:SET ESCAPE OFF执行该命令后, Esc 键处于关闭状态,在程序运行过程中,用户不能通过 Esc 键来中止程序的运行,因为在应用程序中,不希望中止它;而在程序调试阶段,通常不关闭这个键,让程序在运行过程中,随时都可以中断执行,以检查程序中间的运行状况。

格式 一: CANCEL

功能:结束程序的运行,返回命令窗口,同时关闭所有打开的文件。

格式二: SUSPEND

功能:暂时中止程序运行,返回命令窗口。当在菜单中选择【程序】 |【继续执行】时,或在命令窗口中输入 RESUME 命令时,系统再次从中止的地方继续执行程序。

( 2 )、注释命令 格式一: NOTE/ * < 注释字符串 >格式二: && < 注释字符串 >

说明:上述命令不作任何操作,只是注释标记,用于说明程序或命令的功能等。注释内容不需要用定界符定界,执行时也不显示。注释信息如果在一行内没有写完,换行时也必须再写注释命令。 NOTE 或 * 是用于整行注释的,因此,它必须写在每一个注释行的开头;而 && 命令是用于注释一行的部分内容的,因此,它可以写在行中(命令的尾部、注释信息的头部),这是程序中唯一可以在一个逻辑行写二个语句的命令。 USE STUDENT && 打开 STUDENT 表

( 3 )文本显示命令 格式: TEXT

< 文本字符串 > ENDTEXT

功能:将 < 文本字符串 > 原样输出。这条命令通常是用于程序中对用户说明某些问题。

返 回

5.2.2 VFP65.2.2 VFP6 程序设计的条件与循程序设计的条件与循环环 VFP 的程序结构可以分为三种:顺序结构、分支结构、循环结构。

下面将以一个程序演示条件分支结构的循环结构,并对这些概念详细说明。 【例 5-5】假设某单位有很多员工,并且要给月工资高于或等于1000元的员工增加 5% 的工资,给月工资低于 1000元的员工增加 10% 的工资。下面的示例程序将完成这一任务。此示例程序假定已在当前工作区打开了员工工资表,表中有一个名为“月工资”的数值型字段。

*L505CTALK=SET("TALK")SET TALK OFFSCAN

IF 月工资 >=1000REPLACE 月工资 WITH 月工资 *1.05

ELSEREPLACE 月工资 WITH 月工资 *1.1

ENDIFENDSCANSET TALK &CTALKRETURN

在这一示例程序中用到了顺序结构、循环结构和条件分支结构。 1 、条件语句条件分支根据条件的计算结果执行不同的操作。 条件分支结构逻辑流程图 :入口

条件判断真 假

语句序列 1

出口

语句序列 2

VFP 中有两条命令实现条件分支: 格式: IF < 条件表达式 > < 语句序列 1>

[ELSE< 语句序列 2>] ENDIF

单条件选择命令

参数描述:

< 条件表达式 > :指定要计算的逻辑表达式。如果 < 条件表达式> 的值为“真”,则执行 IF 语句之后的 < 语句序列 1> ;如果 <条件表达式 > 的值为“假”,而且包含 ELSE 语句和 < 语句序列2> ,则执行 < 语句序列 2> ;如果 < 条件表达式 > 的值为“假”,而且不包含 ELSE 语句和 < 语句序列 2> ,则程序忽略 IF 语句和ENDIF 语句之间的所有语句,程序从 ENDIF 语句后的第一条命令开始继续往下执行其它程序。

说明:一个 IF…ENDIF 语句块中可以嵌套另一个 IF…ENDIF语句块。

从【例 5-5】所示的程序中可以看到:当当前记录中“月工资”字段的值大于等于 1000元时,将使“月工资 >=1000” 这个条件表达式的值为“真”,此时,程序控制执行 < 语句序列 1>“REPLACE 月工资 WITH 月工资 *1.05” ,即将月工资高于或等于 1000元的工资上调 5% 。否则,即当当前记录中“月工资”字段的值低于 1000

元时,将使“月工资 >=1000” 这个条件表达式的值为“假”,此时,程序控制执行 < 语句序列 2>“REPLACE 月工资 WITH 月工资 *1.1” ,即将月工资低于 1000元的工资上调 10% 。( 2 )多条件选择语句

格式: DO CASE CASE < 条件表达式 1>

< 语句序列 1> [CASE < 条件表达式 2>

< 语句序列 2>…

CASE < 条件表达式 N>< 语句序列 N>]

[OTHERWISE< 语句序列 N+1>]

ENDCASE

参数描述: CASE < 条件表达式 1> <语句序列 1> … : VFP 在执行这条多条件选择命令时,按命令行中写出的条件表达式的顺序逐条检查 < 条件表达式 > ,当遇到第一个结果为“真”的 < 条件表达式 >时,就执行它后面的语句序列。语句序列中的命令逐条被执行,直到遇到下一个 CASE 或 OTHER-WISE 或 ENDCASE ,然后,

再从 ENDCASE 语句后的第一条命令开始继续执行其它命令。 如果一个 CASE < 条件表达式 > 的 < 条件表达式 > 为“假”,就忽略它后面的语句序列。 【例 5-6】运行一个程序,随机输出一条信息:

CLEARAA=INT(RAND()*10) &&随机产生一个 10 以内的整数DO CASE

CASE AA=0? “ 这次产生的随机数是: 0”

CASE AA=1? “ 这次产生的随机数是: 1”

CASE AA=2? “ 这次产生的随机数是: 2”

CASE AA=3? “ 这次产生的随机数是: 3”

OTHERWISE? “ 这次产生的随机数是:大于 3!”

ENDCASE

2 、循环语句程序设计中的循环,是指在程序中从某处开始,有规律地反复执行某一个程序块的现象。 VFP 的循环命令有三类:基于条件的循环、基于计数的循环和基于表的循环。( 1 )基于条件的循环: DO WHILE 命令

格式: DO WHILE < 条件表达式 >[< 语句序列 >][EXIT][LOOP]

ENDDO

参数描述:< 条件表达式 > :指定一个逻辑表达式,它的值决定是否执行 DO WHILE 和 ENDDO之间的命令集合。如果 < 条件表达式 > 的值为“真”,就执行命令集。[< 语句序列 >] :指定当 < 条件表达式 > 计算为“真”时要执行的

[LOOP] :直接将程序控制返回到 DO WHILE 语句,并重新计算条件值。 LOOP 可以放在 DO WHILE 和 ENDDO之间的任何位置。[EXIT] :将程序控制从 DO WHILE 和 ENDDO循环的内部转到ENDDO 后的第一条命令。 EXIT 可以放在 DO WHILE 和 ENDDO之间的任何位置。ENDDO :表明 DO WHILE 语句的结束。 【例 5-7】计算连续自然数之和,并且显示和刚大于 1000 的最后一个自然数。STORE 0 TO AA,BBDO WHILE AA<=1000

BB=BB+1AA=AA+BB

ENDDO? BB结果显示为 45 。

VFP 命令集。

【例 5-8】求连续 N 个不是 7 的倍数的自然数之和,当和是 101的倍数时显示最后的自然数和它们的和。 STORE 0 TO AA,BB && 定义二个变量,用以保存累加值和累加数DO WHILE .T.

BB=BB+1IF MOD(BB,7)=0 &&判断 BB 是否为 7 的倍数 LOOP &&如果 BB 是 7 的倍数则返回去将 BB再加 1ENDIFAA=AA+BB && 将 BB 不是 7 的倍数的连续自然数累加求和

IF MOD(AA,101)=0 &&判断 AA 是否是 101 的倍数 EXIT &&如果 AA 是 101 的倍数,则结束程序的循环ENDIF

ENDDO? BB,AA

屏幕显示结果为 207 和 18483 。

( 2 )基于计数的循环: FOR 命令 格式: FOR < 内存变量 >=< 初始值 > TO < 终值 > [STEP < 步长 >]

< 语句序列 >[EXIT][LOOP]

ENDFOR/NEXT

参数描述:< 内存变量 > :指定作为计数器的内存变量或数组元素。在执行FOR…ENDFOR 语句之前,此内存变量或数组元素不一定存在。< 初始值 > TO < 终值 > : <初始值 > 是计数器的初始值,而 <终值 > 是计数器的终止值。[STEP < 步长 >] :是计数器递增或递减的步长。如果 <步长 >是负值,则计数器递减;如果省略 STEP子句,计数器每次递增1 。< 语句序列 > :指定要执行的 VFP 命令,它可以包含任意数量的命令。

[EXIT] :将控制权交给紧接在 ENDFOR后面的命令。可以在 FOR与 ENDFOR之间的任何地方放置 EXIT。[LOOP] :将控制权直接交给 FOR子句,不再执行 LOOP与 ENDFOR之间的语句。计数器正常递增或递减,就像执行到 ENDFOR子句一样。可以在 FOR与 ENDFOR之间的任何地方放置 LOOP。 说明:可以用内存变量或数组元素作为计数器,指定 FOR…ENDFOR循环中 VFP命令的执行次数。在遇到 ENDFOR或 NEXT之前,始终执行 FOR后面的 VFP命令。执行过程中,每循环一次,计数器都会产生一次计数,计数增量由 <步长 >值控制,然后把计数器的值与 <终值 >进行比较,决定是否进行下一次循环。【例 5-9】求 1到 100中偶数的和 AA=0

FOR II=2 TO 100 STEP 2AA=AA+II

ENDFOR? AA 屏幕显示为: 2550

( 3 )基于表的循环命令 格式: SCAN [< 范围 >] [FOR < 条件 >] [WHILE < 条件 >]

[< 语句序列 >][LOOP][EXIT]

ENDSCAN

参数描述:[< 范围 >] :指定对当前表中记录扫描的范围。只有在范围之内的记录才有可能扫描到。 SCAN 命令的默认范围为 ALL 。[FOR < 条件 >] :只有条件表达式的计算结果为“真”的记录,才能对其执行命令。包含 FOR子句可以筛选出不想扫描的记录。[WHILE < 条件 >] :指定一个逻辑表达式作为执行命令的条件,只要逻辑表达式计算为“真”,就对记录执行命令,直到遇到使表达式不为“真”的记录为止。[< 语句序列 >] :指定要执行的 VFP 命令集。

[LOOP] :把控制权直接交给 SCAN子句。 LOOP子句可以放在SCAN 和 ENDSCAN之间的任何地方。[EXIT] :把控制权力从 SCAN…ENDSCAN循环语句交给 ENDSCAN 下面的命令。 EXIT子句可以放在 SCAN 和 ENDSCAN之间的任何地方。ENDSCAN :标志 SCAN 过程的结束。说明: SCAN 命令自动将记录指针移到下一条满足条件的记录,并执行相应的命令块。【例 5-10】逐条显示 STUDENT 表中男生的情况。USE STUDENTSCAN FOR 性别 =”男”

DISPWAIT

ENDSCANUSE

或者使用下列代码:

USE STUDENTSCAN

IF 性别 #”男”LOOP

ENDIFDISP

WAITENDSCANUSE

3 、使用过程和自定义函数 ( 1 )子程序和过程的调用子程序或过程的编写和修改方式与一般的程序一样,不同的是过程的最后一个语句必须是返回语句( RETURN ),调用过程的程序是主程序,过程可以嵌套,即一个子程序可以再调用其它子程序,但不能形成循环嵌套。子程序或过程的调用也是用 DO 命令: 格式: DO < 过程名 > [IN < 程序文件名 >][WITH < 参数表 >]

功能:执行过程名所指定的子程序。 WITH 用于主程序和子程序间参数的传递。参数描述: < 过程名 > :指定要执行的过程名称。 VFP首先在当前执行的程序中查找此过程,如果在该程序中找不到此过程, VFP 就在用 SET PROCEDURE 命令打开的过程文件中查找此过程,如果还未找到,则以反向调 用顺序在当前打开的其它程序文件中查找此内

内部过程;若仍未找到,则在磁盘上检索以 .FXP 为扩展名的外部过程;若还未找到,最后检索以 .PRG扩展名的外部过程,并把它编译为 .FXP 文件。 在执行一个可执行文件或应用程序中,多个过程可以有相同的过程名。当使用 DO 去启动一个可执行文件或一个应用程序的过程时, VFP 只在可执行文件或应用程序的主程序中搜索指定的过程。IN < 程序文件名 > :执行 < 程序文件名 > 指定的程序文件中的一个过程。当找到该文件时就执行该过程。如果找不到该程序文件,就会显示“文件不存在”的信息。如果找到了程序文件,但指定的过程不存在,就会显示“找不到过程”的信息。[WITH < 参数表 >] :指定要传递给程序或过程的参数。列在 <参数表 > 中的可以是表达式、内存变量、字母和数字、字段或用户自定义函数。默认情况下,参数按引用传递给程序和过程,也可以将参数放在括号中按值传递。传递给程序或过程的参数的最大数目为 27 。

( 2 )子程序或过程的返回语句

格式: RETURN [< 表达式 >/TO MASTER/TO < 过程名 >]

功能:将程序控制权返回给调用程序。参数描述: [< 表达式 >] :指定返回给调用程序的表达式。如果省略 RETURN 命令或省略返回表达式,则自动将“真”返回给调用程序。[TO MASTER] :将控制权返回给最高层的调用程序。[TO < 过程名 >] :将控制权返回给指定的过程。说明:RETURN终止程序、过程或函数的运行,并将控制权返回给调用程序、最高次调用程序、另一个程序或窗口。当执行 RETURN命令时, VFP释放 PRIVATE (专用)类型的内存变量。通常,RETURN放在程序、过程或函数的末尾,用来将控制返回给高层的程序。但是,如果省略 RETURN 命令,一个隐含的 RETURN命令也将被执行。

子程序或过程调用及返回示意图

【例 5-11】计算圆面积的主程序为 MYMAIN.PRG ,子程序为MYSUB.PRG*MYMAIN.PRGCTALK=SET("TALK")SET TALK OFFCLEARSTORE 0 TO RR, AREA

DO WHILE .T.INPUT " 请输入圆的半径: " TO RR

DO MYSUB WITH RR, AREA? " 圆的面积是: ", AREAWAIT "还要继续计算吗( Y/N )? " TO ANSWERIF UPPER(ANSWER)="Y"

LOOPELSE

EXITENDIF

ENDDOSET TALK &CTALK *MYSUB.PRGPROCEDURE MYSUBPARAMETERS R,SS=PI()*R^2RETURN

}以一个独立的文件形式存在

( 3 )过程文件的建立 在实际的程序设计中,需要调用的过程不是一个或二个,而是几个、十几个甚至上百个,这就有可能使打开的文件数超过系统允许打开的文件数,而且将导致磁盘目录过于庞大,使系统调用文件的速度降低,程序执行速度也随之下降,因而有必要将若干个过程按一定的规定放在一个大文件中,这个文件称为过程文件。1 )过程文件的建立命令格式与建立程序文件一样:

格式: MODIFY COMMAND < 过程文件名 >

过程文件的格式要求每个过程文件的开头必须用下列语句: 格式: PROCEDURE < 过程名 >

功能:标明是一个过程。参数描述:< 过程名 > :指定过程名称。命名方法与文件名的命名方法相同。

过程文件的内容如下: PROCEDURE < 过程名 1>< 语句序列 1>RETURNPROCEDURE < 过程名 2>< 语句序列 2>RETURN……PROCEDURE < 过程名 N>< 语句序列 N>RETURN

说明:在一个过程文件中可以包含多个过程,在同一个过程文件中不允许出现相同的过程名,如果有相同的过程名,则只有第一次出现的过程才有被调用的可能。一个过程文件中最多允许包含 128 个过程。

2 )过程文件的调用过程文件和表文件一样,都是在先打开后才能使用。

①过程文件的打开命令 格式: SET PROCEDURE TO < 过程文件名 >

在主程序中应先打开过程文件,将过程文件中的所有过程都调入

内存(打开一个过程文件只算打开了一个文件) 当过程文件不再用时应将其关闭,以节省内存空间。系统允许打开一个过程文件,当打开另一个过程文件时,先已打开的过程文件系统会自动将其关闭。【例 5-12】程序中常用到计算圆面积、长方形面积、阶乘等,现将它们编为三个过程,放在一个过程文件( MYPROCED.PRG )中,被主程序 MYMAIN.PRG 调用。 *MYMAINCLEARTEXT这是一个计算圆面积、长方形面积、阶乘等的程序,先输入功能选择: 1-- 计算圆面积; 2-- 计算长方形面积; 3-- 计算阶乘; 4--退出。再输入参数:所有数据之间用逗号" , " 分隔。如计算长方形面积则在下面的提示信息后面输入 2 , 10 , 15 。ENDTEXTCTALK=SET("TALK")SET TALK OFFSET PROCEDURE TO MYPROCED DO WHILE .T.ACCEPT " 请输入您的功能选择及参数: " TO SELECTPROGNAME="PROGRAM"+SUBSTR(SELECT,1,1)

IF (SUBSTR(SELECT,1,1)="1".OR. SUBSTR(SELECT,1,1)="3").AND.OCCURS(",",SELECT)#1;.OR.SUBSTR(SELECT,1,1)="2".AND.OCCURS(",",SELECT)#2.OR.SUBSTR(SELECT,1,1)>"4";.OR.SUBSTR(SELECT,1,1)<"1"

WAIT WINDOW AT 15,20 " 输入的参数错误,请重新输入! " NOWAITLOOP

ELSEIF SUBSTR(SELECT,1,1)="4"

EXITENDIF

ENDIFIF OCCURS(",",SELECT)=1

POSITION=ATC(",",SELECT,1)AA=VAL(SUBSTR(SELECT,POSITION+1,LEN(SELECT)-POSITION))DO (PROGNAME) WITH AA

ELSEPOSITION1=ATC(",",SELECT,1)POSITION2=ATC(",",SELECT,2) AA=VAL(SUBSTR(SELECT,POSITION1+1, LEN(SELECT)-POSITION1))BB= VAL(SUBSTR(SELECT,POSITION2+1,LEN(SELECT)-POSITION2))DO (PROGNAME) WITH AA,BB

ENDIFENDDOCLOSE PROCEDURESET TALK &CTALKRETURN

*MYPROCEDPROCEDURE PROGRAM1PARAMETERS RS=PI()*R^2? " 半径为 "+ALLTRIM(STR(R))+" 的圆的面积为: ",SRETURNPROCEDURE PROGRAM2PARAMETERS LONG,WIDTHS=LONG*WIDTH? " 长为 "+ALLTRIM(STR(LONG))+" 宽为 "+ALLTRIM(STR(WIDTH))+;" 的长方形的面积为: ",SRETURNPROCEDURE PROGRAM3PARAMETERS RN=1T=1DO WHILE N<=R

T=T*NN=N+1

ENDDO? "值为 "+ALLTRIM(STR(R))+" 的阶乘为: ",TRETURN

③递归调用在过程中不但可以调用另外一个过程,而且还可以调用自己,这就叫递归调用。【例 5-13】求一个 30 以内的自然数的阶乘。

*MYMAIN.PRGCTALK=SET("TALK")SET TALK OFFSET PROCEDURE TO MYSUBINPUT “ 请输入一个 30 以内的正整数:” TO NUMBERII=1DO MYSUB WITH NUMBER,IICLOSE PROCEDURESET TALK &CTALKRETURN *MYSUB.PRGPROCEDURE MYSUBPARAMETERS MM,NNIF MM>1

DO MYSUB WITH MM-1,NN &&递归调用。请注意同下一句的次序NN=NN*MM && 计算乘积。

ENDIF? STR(MM,2)+”! =”+STR(NN,10)RETURN 返 回

5.3 VFP65.3 VFP6 程序设计步骤 程序设计步骤 5.3.1 对任务进行说明

退 出退 出

5.3.2 分解问题 5.3.3 编制模块 5.3.4 测试模块

5.3.5 组装全部模块 5.3.6 整体测试

5.3.7 提高程序的可靠性 5.3.8 将程序定义为过程或函数

返 回

也可以使用循环结构多次重复执行相同的操作。因为用以测试的字符串有固定的字符数( 15 ),即使在表的记录中这个字段的长度不是定长,也能够使用 FOR循环命令。因为 FOR循环的计数器每执行一遍增 1 ,因此,可以在 SUBSTR()函数中使用该计数器。所以可以编写一个示例程序:

FOR II=1 TO 15?? SUBSTR(cTest,II,1)

ENDFOR将此程序保存为 L508.PRG 后运行

运行结果123_456_7 8 9_0

2 、判断字符是否为数字从字符串中分离出单个字符之后便可以判断它是否为数字。在命令窗口中输入如下命令:

? ISDIGIT(“2”) 运行结果

.T.? ISDIGIT(“_”) ? ISDIGIT(SUBSTR(cTest,10,1))

.F.

.F.

3 、若字符为数值,将它复制到新串中既然可以逐一检查字符是否为数值,下面可以使用内存变量来保存该数字。为了创建一个变量,需要给它赋一个初值——一个零长度的字符串。cNumbVar=””因为 FOR循环扫描整个字符串,所以最好用一个变量暂存每次分离出来的字符以便处理。cCharacter=SUBSTR(cTest,II,1)提示:在计算、求值以及在函数中得到的结果,最好保存在内存变量中,这样便于直接处理这些变量而不必重新计算或求值。可以使用以下代码将每个被确认为数字的字符添加到新串中:cNumbVar=cNumbVar+ cCharacter

完整的程序

cNumbVar=””FOR II=1 TO 15

cCharacter=SUBSTR(cTest,II,1)IF ISDIGIT(cCharacter) cNumbVar=cNumbVar+ ccharacterENDIF

ENDFOR 返 回