常用编程命令及常用函数.doc_第1页
常用编程命令及常用函数.doc_第2页
常用编程命令及常用函数.doc_第3页
常用编程命令及常用函数.doc_第4页
常用编程命令及常用函数.doc_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

常用编程命令及常用函数注:在语法中如用方括号“ ”括起来的词句,表示可以不用。常用命令假设(if.endif)循环(do while.enddo)分支(do case.endcase)赋值(store.to)调用表单(do form)调用子程序(do)返回调用程序(return)启动事件处理(read events)清除事件处理(clear events)开关命令执行状态(set talk on/off)结束程序(cancel)常用函数数值转换字符(str()字符转换数值(val()取系统日期(date()取年份(year()取月份(month()取天日(day()取整(int()四舍五入(round()删除标记(delete()记录号(recno()记录数(reccount()找到记录(found()表结尾(eof()表开头(bof()消除后续空格(trim()消除前导空格(ltrim()假设语句根据一逻辑表达式的值,有条件的执行一组命令。语法:IF 逻辑表达式 THEN 程序组1ELSE 程序组2ENDIF参数:逻辑表达式代表一逻辑值,如果这逻辑值为真,系统执行程序组1,否则不执行程序组1,如果有else及程序组2的话,则执行程序组2,如没有则什么也不执行,直接执行endif后面的语句。备注:在if.endif之间还可以有if.endif,即该命令是可以嵌套的。then可以有也可以没有,对程序没有影响。else及程序组2可以有也可以没有,但如果有的话,在逻辑表达式的值为假时,程序组2将被执行。if 与 endif 必须配对使用,即有一个 if 必须有一个 endif, 否则程序会出错。举例:例1:假如分数字段的值大于等于90,则让等级字段的值为“优”,并显示该记录。程序如下:if 分数=90 replace 等级 with 优 displayendif例2:在数据库中可以把性别字段设为逻辑型,“真”代表“男”,“假”代表“女”,但显示时不能显示真、假,否则别人看不懂,而应显示男、女,因此我们设一变量xb,根据性别字段的具体值,将xb的值设为男或女,然后在需要的时候显示xb的值即可。程序如下:if 性别 xb=男else xb=女endif其中第一句:if 性别,表示“假如性别为真”的意思,不要写成“if 性别=.t.”。以上程序也可以写成如下形式,效果相同:if .not. 性别 xb=女else xb=男endif即,假如性别不为真的话,xb的值就为女,否则为男。循环语句(do while.enddo)根据条件重复执行一组程序。语法:DO WHILE lExpression Commands LOOP EXITENDDO参数:lExpression 为一逻辑表达式,其值如果是“真”,即执行commands程序组,如果表达的值为“假”,则跳过该段程序组,执行enddo后面的语句。Commands 当表达式 lExpression 值为真时所要执行的程序组。LOOP 此为 do while.enddo 命令的一个子句,它可以放在 commands 程序组中间的任何地方,当程序一旦执行到该子句时,则返回 do while 重新执行。此子句根据需要可以有,也可以没有。EXIT 与loop一样是 do while.enddo 命令的一个子句,它可以放在 commands 程序组中间的任何地方,当程序一旦执行到该子句时,则跳出循环,执行enddo后面的语句。此子句根据需要可以有,也可以没有。备注:程序一旦执行到do while 语句,如果 lExpression 的值为真,则执行 commands 程序组,该程序组执行完后,就到enddo语句,enddo会将程序返回 do while 再次验证 lExpression 是否为真,如仍是,则又一次执行 commands ,如此循环往复,直到 lExpression 为假,或遇上 exit 语句。该语句可以嵌套,即循环中还可以有循环。do while 与 enddo 必须配对使用,即有一个 do while 必须有一个 enddo 否则程序会出错。举例:例1:在数据库中不断将记录指针往下移,直到数据库结尾。程序如下:do while .not. eof() skipenddo例2:在上面的例子加入此功能,当遇到性别字段为“女”时,跳出循环。程序如下:do while .not. eof() if 性别=女 exit endif skipenddo例3:不断将记录指针往下移,当遇到数量字段的值大于等于600时退出循环,如遇到值小于400的,将其值乘2,然后再检验一次是否大于600,如是则退出循环。程序如下:do while 数量600 if 数量400 replace 数量 with 数量*2 loop endif skipenddo分支语句(do case.endcase)根据不同的条件执行不同的程序组。语法:DO CASE CASE 逻辑表达式1 程序组1 CASE 逻辑表达式2 程序组2 . CASE 逻辑表达式n 程序组n OTHERWISE 程序组0ENDCASE参数:CASE 逻辑表达式 程序组 . 当程序执行到 do case 时,便检验第一个 case 的逻辑表达式(逻辑表达式1)是否为真,如不为真,接着检验第二个 case 的逻辑表达式,以此类推直到逻辑表达式n。当检测到第一个为真的逻辑表达式时,便执行跟随在其后面的程序组,执行完后跳过后面所有的 case ,接着执行 endcase 后面的语句,也就是说即使后面还有为真的逻辑表达式也不执行了。如果所有 case 后面的逻辑表达式都为假,则执行 otherwise 后面的程序组(如果有的话, otherwise 及其程序组是可以没有的,如果没有则什么都不做,直接执行 endcase 以后的程序)备注:在do case 和 endcase 之间可以有任意多个 case 。do case 和 endcase 必须配对使用,即有一个 do case 必须有一个 endcase ,否则程序会出错。举例:如果工资在200元以下,增加50%;300元以下,增加30%;500元以下,增加20%;其它增加10%。程序如下:do case case 工资=200 replace 工资 with 工资*1.5 case 工资=300 replace 工资 with 工资*1.3 case 工资=500 replace 工资 with 工资*1.2 otherwise replace 工资 with 工资*1.1endcase在这里要注意一个问题,不能把300元的 case 放在200元之前,否则一个100元的,按理应加50%,但当遇到小于300元的 case 时,其逻辑表达式为真(小于200元的肯定小于300元),因此就会执行后面的程序,加30%,并且执行完后,就不再执行其它的 case 了,这样就产生了错误的结果,所以应按从小到大的顺序来排列。赋值语句(store.to)将一个数据赋给一个变量。语法:STORE 表达式 TO 变量名表参数:表达式的值即为要赋给变量的数据。变量名表即为要被赋值的各变量。在这里可以是一个变量,也可以是多个变量,如果有多个变量,其间用“,”(逗号)隔开。备注:如果是给一个变量赋值,该语句可写成如下形式:变量名=表达式表达式可以是一个数值,也可以是一个算术式。举例:例1:将3赋给ab、xyz、jfz三个变量,程序如下:store 3 to ab,xyz,jfz例2:将变量gz的值加100赋给yfgz。程序如下:yfgz=gz+100调用表单语句运行一个由表单设计器设计的表单文件。该文件是经编译过的。语法:DO FORM 表单文件名 NAME 变量名 LINKED参数表单文件名即是要运行的由表单设计器设计的表单文件名称。变量名为调用该表单所用的变量名称,做为表单,不能直接用这的名称去调用它,必须将其赋给一个变量,然后用这个变量来调用它。如果您不会在这个表单之外调用它,也可以不要这个变量。在程序中产生的所有变量在程序运行结束后将被释放,即这些变量不再存在,因此也就无法继续调用这些变更,如果为了调试程序需要在程序运行结束后在命令窗口中调用这个表单,必须加上 linked 子句。举例:在程序中调用xy7表单,并将赋给一个变量lucky,程序如下:do form xy7 name lucky调用子程序语句(do)运行一个VFP程序。当我们要在一个程序中调用另一个程序(子程序)时使用此命令。语法:DO 程序名参数:程序名即为被调用的程序名称。备注:如被调用的程序的扩展名是“prg”,调用时可不用带扩展名,否则要带上扩展名。举例:有一个程序,名称为 xy7.prg,调用它的程序如下:do xy7返回调用程序语句(return)返回调用本程序(该语句所在程序)的程序。前面讲过调用子程序的语句,从一个程序A调用另一个程序B后,系统便开始执行B程序中的语句,到一定时候往往要从程序B返回程序A,便可使用该语句。语法:RETURN备注:程序A调用程序B,当从B返回A后,系统接着执行调用语句(do b)下面的一条语句。举例:程序a.prg如下:do while .not. eof()if 工资100do bendifskipenddo程序b.prg如下:replace 工资 with 工资*1.5 &将工资增加50display &显示出该记录,这样可以将所有增加了工资的记录显示出来return首先执行程序a.prg,当程序执行到 do b 语句时,便转去执行程序 b.prg ,在程序 b 中执行到 return语句时,又返回程序 a ,并接着执行 do b 的下一条语句 endif 。启动事件处理语句(read events)启动VFP的事件处理程序。语法:READ EVENTS备注:当该命令执行后,系统即停止继续执行后续的语句,这时我们可以调用之前所启动的菜单、表单等对象,并用这些对象的事件程序去完成相应的任务,直到发出 clear events 命令,系统才接着执行 read events 后面的命令语句。可能初学者看了上面的内容还不是很清楚,不要紧,我们在后面课程中会进一步讲解。清除事件处理语句(clear events)终止由 read events 语句启动的事件处理程序。语法:clear events备注:发出该命令后,系统将继续执行 read events 之后的语句。开关命令执行状态语句(set talk on/off)确定是否显示VFP命令执行的状态。语法:SET TALK ON | OFF参数:ON 显示VFP命令执行的状态。OFF 不显示VFP命令执行的状态。备注:使用时,on、off 二者之中必须选择一个。很多VFP命令执行后,会显示执行后的结果状态,如 locate for 命令执行,如找到记录的会显示被找到的记录号,否则会显示“已到文件尾”,但一般我们在程序中是不需要这些显示的,比如找到了记录就直接显示出来,没找到一般用一个对话框来给出更清楚的提示,所以在程序一开始往往要将 set talk 关闭。结束程序语句(cancel)结束当前正在运行的所有程序,返回VFP或操作系统。语法:cancel备注:数值转换字符函数(str()返回与指定数值表达式对应的字符。语法:str(数值表达式,长度,小数位数)返回值的类型字符型参数:数值表达式:要被转换为字符的数值表达式。长度:转换后字符的长度。该长度等于小数点和小数点右边第个数字所占字符的数目总和。如果指定长度大于所需长度,自动在前面加空格补齐。如果指定长度小于所需长度,返回一串星(*)号,表示数值溢出。如省略长度,则默认长度为10。小数位数:指定返回字符串中的小数位数。如指定位数小于实际位数,则返回值四舍五入。如指定位数大于实际位数,则加0补齐。如省略小数位数,默认为0。在指定了小数位数的情况下,如指定长度(第二个参数)小于总长度,但大于整数长度,则返回对小数部分做了四舍五入的字符。备注:返回后的值看起来还是数的形式,但它的数据类型已经变了,不再是一个数值,也就是不能再用来做加、减、乘、除的算术运算,但可以和字符进行加减。比如:? 季度+1就会出错,因为一个字符是不能和一个数值相加的。写成如下形式就可以了:? 季度+str(1,1)结果是:季度1注意,这里一定要指定长度,否则由于默认长度是10,就会出现如下结果:季度 1假如不知道数值有几位数怎么办呢?请参见ltrim()函数。字符转换数值函数(val()将数字组成的字符表达式转换成数字值。语法:val(字符表达式)返回值的类型数值型参数:字符表达式:要被转换为数值的字符表达式。该表达式由最多16位的数字组成,若超过16位,则对其圆整。备注:val()函数从左到右返回字符表达式中的数字,直到遇到非数值型字符(忽略前面的空格)时为止。若字符表达式的第一个字符不是数字,也不是正、负号,则返回0。举例:a=123如果按下面的写法,就会出错,因为一个字符不能与一个数值相加:? a+3写成如下形式便可以了:? val(a)+3结果是126。取系统日期函数(date()返回由操作系统控制的当前系统日期。语法:date()返回值的类型日期型取年份函数(year()从指定的日期表达式中返回年份。语法:year(日期表达式)返回值的类型数值型参数:日期表达式:指定的日期表达式,该函数即是返回其年份值。举例:? year(date()如果当前的系统日期是1999年2月5日,则显示的结果为1999。取月份函数(month()从指定的日期表达式中返回月份。语法:month(日期表达式)返回值的类型数值型参数:日期表达式:指定的日期表达式,该函数即是返回其月份值。举例:? month(date()如果当前的系统日期是1999年2月5日,则显示的结果为2。取天日函数(day()以数值型返回日期表达式是当月的第几天。语法:day(日期表达式)返回值的类型数值型参数:日期表达式:指定的日期表达式,该函数返回该日期是当月的第几天。举例:? day(date()如果当前的系统日期是1999年2月5日,则显示的结果为5。取整函数(int()返回数值表达式值的整数部分。语法:int(数值表达式)返回值的类型数值型参数:数值表达式:指定的数值表达式,该函数返回其整数部分。举例:? int(123.47)结果是123。四舍五入函数(round()对指定表达式进行四舍五入运算,并把结果返回。语法:round(数值表达式,小数位数)返回值的类型数值型参数:数值表达式:指定的数值表达式,该函数返回其四舍五入后的值。小数位数:保留的小数位数。举例:? int(123.457,2)结果是123.46。删除标记函数(delete()确定当前记录是否已做删除标记,若已做删除标记,返回真(.t.),否则返回假(.f.)。语法:delete(表别名|工作区)返回值的类型:逻辑型参数:表别名|工作区:该参数指定所要确定的表的别名或所在工作区,即您可以在一个工作区去检测另一工作区的表的记录是否做了删除标记,而另一工作区的表可用其别名或工作区号来指定。该参数如省略,隐含为当前工作区,如有该参数的话,别名或工作区只选一个。记录号函数(recno()返回当前表或指定表中的当前记录号。语法:recno(表别名|工作区)返回值的类型:数值型参数:表别名|工作区:该参数指定所要确定的表的别名或所在工作区,即您可以在一个工作区去得到另一工作区的表的当前记录号,而另一工作区的表可用其别名或工作区号来指定。该参数如省略,隐含为当前工作区,如有该参数的话,别名或工作区只选一个。记录数函数(reccount()返回当前表或指定表中的记录数目。语法:reccount(表别名|工作区)返回值的类型:数值型参数:表别名|工作区:该参数指定所要确定的表的别名或所在工作区,即您可以在一个工作区去得到另一工作区的表的记录数,而另一工作区的表可用其别名或工作区号来指定。该参数如省略,隐含为当前工作区,如有该参数的话,别名或工作区只选一个。找到记录函数(found()如果locate、continue、seek等查找记录的命令成功(即找到了记录),该函数返回“真”(.t.),否则返回“假”(.f.)。语法:found(表别名|工作区)返回值的类型:逻辑型参数:表别名|工作区:该参数指定所要确定的表的别名或所在工作区,即您可以在一个工作区知道另一个工作区上次查找记录是否找到,而另一工作区的表可用其别名或工作区号来指定。该参数如省略,隐含为当前工作区,如有该参数的话,别名或工作区只选一个。举例:locate for 姓名=庄稼?found()如找到记录,显示结果为.t.,否则为.f.。表结尾函数(eof()确定记录指针是否在表的结尾处。语法:eof(表别名|工作区)返回值的类型:逻辑型参数:表别名|工作区:该参数指定所要确定的表的别名或所在工作区,即您可以在一个工作区知道另一个工作区表的指针是否在尾部,而另一工作区的表可用其别名或工作区号来指定。该参数如省略,隐含为当前工作区,如有该参数的话,别名或工作区只选一个。备注:这里所说的结尾处,并非是指最后一个记录,而是最后一个记录的后面,即没有记录。举例:go bottomskip?eof()显示结果为.t.。如果没有skip,仅仅走到最后一个记录,返回的将是.f.,而必须再往下跳一下才会是“真”结尾。此时如输入命令:display,则没有记录显示。这一点与bof()函数不同。表开头函数(bof()确定记录指针是否在表的开头。语法:bof(表别名|工作区)返回值的类型:逻辑型参数:表别名|工作区:该参数指定所要确定的表的别名或所在工作区,即您可以在一个工作区知道另一个工作区表的指针是否在开头,而另一工作区的表可用其别名或工作区号来指定。该参数如省略,隐含为当前工作区,如有该参数的话,别名或工作区只选一个。备注:这里所说的开头,并非是指第一个记录,而是第一个记录的前面。举例:go topskip -1?bof()显示结果为.t.。如果没有skip -1,仅仅走到第一个记录,返回的将是.f.,而必须再往上跳一下才会是“真”开头。但与eof()函数不同,此时如输入命令display,将显示第一条记录。消除后续空格函数(trim()将字符表达式的后续空格全部删除,并将结果返回。语法:trim(字符表达式)返回值的类型:字符型参数:字符表达式:指定的字符表达式,该函数将删除其后续空格。备注:trim()函数等同于rtrim()函数。举例:如表的“姓名”字段长度为10,当前内容为“张三”,那么如下语句:? 姓名+先生:其显示结果是:张三 先生:而语句:? trim(姓名)+先生:显示结果是:张三先生消除前导空格函数(ltrim()将字符表达式前面的空格全部删除,并将结果返回。语法:trim(字符表达式)返回值的类型:字符型参数:字符表达式:指定的字符表达式,该函数将删除其后续空格。举例:在讲str()函数时我们举过一个例,即把一个字符与一个数值相加时,应采用如下形式:? 季度+str(1,1)但是当我们没有办法确定这个数值的位数时,这个办法就行不通了,您不可能规定它的长度只能是1或2等等。那么怎么办呢,采用ltrim()函数可以解决了:? 项目+ltrim(str(sz)这里假设事先已有一个数值存入了sz变量,但不知道这个数值是几,也就更不知道有几位数,那么在隐含状态下,str()函数将把sz转换为长度为10的字符,其前面可能有若干空格,通过ltrim()函数的处理,不论前面有多少空格,都可以得到如下结果(假设数值是15):项目15更多编程命令BLANKCALCULATECOPY FILE COPY STRUCTURE EXTENDEDFLUSHFOR.ENDFORON ERRORON ESCAPEON KEY LABELPACK DATABASESCAN.ENDSCANSET CONFIRMSET DEFAULTSET SKIP TOSET SKIP OFVALIDATE DATABASEBLANK 命令如果发出该命令时不带任何参数,则清除当前记录中所有字段的数据。语法BLANK FIELDS 字段名列表 范围 FOR 条件 WHILE 条件 NOOPTIMIZE说明如果使用了字段名列表,则清除指定字段中的数据,另外也可以在字段名前面加上别名,以清除其它工作区的表中数据,但要注意一点,如果当前工作区的记录指针指在了表的末尾,那么它也不能清除您所指定的其它工作区中的字段,即使其它工作区的记录指针没有指向末尾。COPY FILE 命令复制文件。语法COPY FILE 文件名1 TO 文件名2说明文件名中可以用“*”和“?”,如 *.prg。要注意的一点是“文件名2”必须有,比如:copy file *.prg to c:temp*.prg不象 DOS 的 COPY 命令可以没有目的文件名,而且命令中的“FILE”也一定要有。COPY STRUCTURE EXTENDED 命令将当前工作区的表结构信息复制到另一表中。语法COPY STRUCTURE EXTENDED TO 表文件名 FIELDS 字段名表参数说明FileName :指定结构信息所存放的表文件名。FIELDS 字段名表 :指定需要复制表结构中哪些字段的信息,如省略,则复制所有字段的信息。说明该命令将一个表的各字段信息复制到一个新表中,每个字段为一个记录,这是一个专门的表,其字段是固定,这些字段分别记录各字段的字段名、长度、数据类型等等,各字段的字段名及其意义如下:字段名数据类型意义FIELD_NAME字符字段名。FIELD_TYPE字符数据类型。C=字符型,Y=货币型,N=数值型,F=浮点型,I=整数型,B=双精度型,D=日期型,T=日期时间型,L=逻辑型,M=备注型,G=通用型FIELD_LEN数值字段长度。FIELD_DEC数值小数位数。FIELD_NULL逻辑字段是否可用 null 值。FIELD_NOCP逻辑字段是否允许代码页翻译。FIELD_DEFA备注字段的隐含值。FIELD_RULE备注字段验证规则。FIELD_ERR备注字段验证规则出错时的提示信息。TABLE_RULE备注表验证规则。TABLE_ERR备注表验证规则出错时的提示信息。TABLE_NAME字符长表名。INS_TRIG备注插入触发器代码。UPD_TRIG备注更新触发器代码。DEL_TRIG备注删除触发器代码。TABLE_CMT备注表说明。如图1,即为用 COPY STRUCTURE EXTENDED 命令生成的 rsda 表的结构信息表,在这个表中就可以看到 rsda.dbf 表的各字段情况。那么用这个命令产生的结构信息表有什么用呢?这可以让我们在编程时改变一个表的结构,因为信息结构表也是个表,我们可以象操作一般表一样去修改它的内容,当然修改时要遵从表结构的有关规定,比如字段名不能超过10个字符,字段类型必须是上表中的字符之一,字段名不能重名等等。当然我们修改了这个表后不会对原表马上产生作用,因为它们已经是分别独立的两个表,在物理上没有任何联系,但我们可以首先使用以下命令:CREATE 表文件名 FROM 结构信息表文件名根据结构信息表创建一个新表,再将原表的数据加到这个新表中,删除原表,将新表改为原表名,这样就修改了表的结构。比如,我们要将 rsda 表部门字段的长度改为20,程序如下:select rsda &选择 rsda 表。copy structure to rsdajg extended &将 rsda 表的结构信息复制到 rsdajg 表。use rsdajg &打开 rsdajg 表,同时关闭 rsda 表。replace field_len with 20 for trim(field_name)= =部门 &将部门字段的字段长度修改为20。*实际上上一句的意思是将 rsdajg 表的 field_name 为“部门”的记录的 field_len 字段值改为20。use &关闭 rsdajg 表,要从这个表创建新表,必须将其关闭。create rsda2 from rsdajg &从 rsdajg 中提取信息创建 rsda2 表。append form rsda &从 rsda 表中获取数据。erase rsda.dbf &删除 rsda.dbf 表。rename rsda2.dbf to rsda.dbf &将 rsda2.dbf 改名为 rsda.dbf。FLUSH 命令将表和索引中的数据存入磁盘。语法FLUSH说明当我们修改一个表时,修改完后,我们可能并不马上将表关闭,那么这时所做的修改可能只是在内存中,而没有真正存到盘,如果这时死机或停电,那么.,所以我们可以在程序适当的地方用此命令确保数据存盘。比如,我们可以在菜单中加个“保存”命令,该命令就调用 FLUSH 语句,供操作者在适当的时候调用此命令来保存数据。还可以用一个表单,在其中放一个计时器,在计时器的 timer 事件中用此命令,这样就做成一个具有自动保存数据的功能,甚至可以在菜单中加一个设置计时器时间的命令,以供操作者设置自动保存数据的间隔时间。FOR.ENDFOR 命令按指定的次数循环执行一组命令。语法FOR 变量=初始值 TO 结束值 STEP 步长值 命令组 EXIT LOOPENDFOR | NEXT参数描述变量:指定一个变量作为计数器,该变量可以不预先存在,FOR 命令会自动创建。初始值 TO 结束值:即计数器的初始值和结束值,也就是指定循环的次数。STEP 步长值:设定计数器每次增加或减少的量,如果省略此子句,则每次增加1,比如 for jsq=1 to 10,那么将会循环10次,如果是 for jsq=1 to 10 step 2,那么循环将会是5次,因为每循环1次计数器增加2,从1到10只需增加5次就行了。可能有人会问了,既然循环5次,那为什么不 for jsq=1 to 5 呢?这往往是为了在某些情况下使程序编起来方便和易于理解,比如要对数据表中的记录进行某项操作,要求每隔一条记录做一次,起始和结束的记录是根据具体情况变化的,也就是初始值和结束值都是变量,那么我们就可以使用步长子句,并将步长设为2,这样就不用具体去计算到底需要多少次循环了,如果再加上步长也是变量,即有时隔一条记录,有时会隔多条记录,则步长子句就更必要了。注意步长的变化是指在不同次的完整循环中步长会变,一般在一次完整的循环中不要更改初始值、结束值和步长。另外步长可以是负的,这又有什么必要?当我们需要根据一个数值不断减小来进行某项操作时就需要了,比如我们需要对记录进行某项操作,这个操作要求先处理第10条记录,再第9条(因为在处理第9条时需要根据第10条的情况),依次到第1条,那么我们就可以:for jsq=10 tp 1 step -1* 操作命令组 go jsq &设上面的操作移动了记录指针,此时已不指在第10条记录上,则不能用 skip -1 将指针移到第9条endfor很明显,虽然可以用其它方法,但这样编出的程序最简洁,一目了然。EXIT 和 LOOP:与 DO WHILE 中的意义一样。说明计数器只有在大于结束值时才结束循环,即当计数器等于结束值时仍要循环,也就是说:for jsq=1 to 10是循环10次,而不是9次,也就是当 jsq 的值为10时,还要循环一次,当它为11时,则退出循环,执行 endfor 之后的程序。注意DO WHILE.ENDDO 与 FOR.ENDFOR 都是循环,它们有什么区别呢?在需要使用计数器的情况下,由于 FOR.ENDFOR 不需要专门的计数语句,所以程序执行的速度快,因此能用 FOR.ENDFOR 时尽量用。ON ERROR 命令设置一命令,当系统错误发生时,该命令执行。这也就是程序员们常说的错误捕获陷井。所谓错误捕获陷井的意思就是在系统中启动一个监控程序,一旦错误发生,这个监控程序就将错误捕获,并不让错误显示出来,可保证程序的继续运行,然后用一个命令去对出现的错误进行处理,比如显示一个错误提示等。如果错误不发生,这个命令则始终不执行。语法ON ERROR 命令参数说明命令:此即为指定的在捕获错误后所要执行的程序。一旦程序执行到某个语句发生错误,该命令即被执行,执行完后,接着执行发生错误的下一条语句。提示有时为了对错误进行处理,一条命令可能是不够的,则可用该命令调用一个子程序,那么需要在子程序执行完后才接着执行发生错误的下一条语句。 如果子程序中有 RETRY 命令,该命令将使子程序返回,并重新执行发生错误的语句,这个命令一般用在这种情况下,当子程序对错误进行了处理,使得再执行该命令时不会发生错误了,这样就可以使程序按照正常情况运行下去。多学一招当处理错误子程序执行时,您还可以用 ERROR(), MESSAGE(), LINE(), PROGRAM() 等函数返回出错的编号、信息、出错的语句所在行号以及出错的程序等,这些可能对处理错误有帮助。如省略命令参数,则取消错误捕获陷井。说明ON ERROR 命令不能嵌套,也就是说在 ON ERROR 所执行的子程序中不能再有 ON ERROR 命令,否则等于取消错误捕获。示例当 DBF 文件的结构化复合索引损坏时,如果您打开 DBF 文件就会出错,下面的例子就捕获错误并自动修复索引:*主程序on error do xfsy &设置错误陷井use rsda &打开表,如果索引损坏,则会产生错误,xfsy 程序将会执行on error &取消错误陷井.cancel *修复子程序procedure xfsy &修复子程序的过程名erase rsda.cdx &删除索引文件use rsda &打开表index on 编号 tag of rsda.cdx &重建索引“编号”index on 姓名 tag of rsda.cdx &重建索引“姓名”ON ESCAPE 命令设置一命令,当按了ESCAPE时,该命令执行。语法ON ESCAPE 命令参数说明命令:该命令即为指定的按下 ESC 键后所要执行的命令。假设当程序执行到第10条语句时您按下了 ESC,那么在命令执行完后,将接着执行第11条语句,如果命令是调用一个子程序,而子程序中有 RETRY 语句,则返回重新执行第10句。说明假如 ON KEY LABEL 命令也同时指定了 ESC 键,ON ESCAPE 所指定的命令优先执行。如 SET ESCAPE OFF 则该命令也不起用。注意这个命令常常用来在一个循环中退出循环,比如: on escape exitdo while .t. *循环体中的命令组enddoon escape这样在循环中执行命令时,只要您随时动用您的玉指按下 ESC 键,即可令程序退出循环。但别高兴得太早,上面这个程序在执行时常常出错,但也不是总出错,为什么呢?因为 exit 命令必须在循环体中,假如程序正执行到 do while 或 enddo,这时您动了玉指,程序就会出错,怎么解决这个问题呢?这样:on escape tc=.t.tc=.f.do while .t. *循环体中的命令组 if tc exit endifenddoon escape思考题:上面这个程序为什么不会出错?ON KEY LABEL 命令指定一个命令,当键盘上某个键(也可以是组合键或鼠标)被按下后,该命令执行。语法ON KEY LABEL 键名 命令参数描述各键的键名如下:键键名LEFTARROWRIGHTARROWUPARROWDNARROWHOMEHOMEENDENDPAGE UPPGUPPAGE DOWNPGDNDELDELBACKSPACEBACKSPACESPACEBARSPACEBARINSINSTABTABSHIFT+TABBACKTABENTERENTERF1 to F12F1, F2, F3 .CTRL+F1 to CTRL+F12CTRL+F1, CTRL+F2 .SHIFT+F1 to SHIFT+F12SHIFT+F1, SHIFT+F2 .ALT+F1 to ALT+F12ALT+F1, ALT+F2, ALT+F3 .ALT+0 to ALT+9ALT+0, ALT+1, ALT+2 .ALT+A to ALT+ZALT+A, ALT+B, ALT+C .CTRL+LEFT ARROWCTRL+LEFTARROWCTRL+RIGHT ARROWCTRL+RIGHTARROWCTRL+HOMECTRL+HOMECTRL+ENDCTRL+ENDCTRL+PAGE UPCTRL+PGUPCTRL+PAGE DOWN CTRL+PGDNCTRL+A TO CTRL+ZCTRL+A, CTRL+B, CTRL+C .CTRL+0CTRL+0RIGHT MOUSE BUTTONRIGHTMOUSELEFT MOUSE BUTTONLEFTMOUSEMOUSE BUTTONMOUSEESCESCON KEY LABEL 键名 后面不跟命令则解除该键所要执行的命令(即解除所设的程序陷井)。说明该命令的用法与 ON ESCAPE 的用法基本上是一样的。注意该命令对于在系统菜单及系统对话框上的按键不起作用。 对于 on mouse 等命令,在鼠标点击件时不起作用。示例on key label ctrl+e tc=.t.tc=.f.do while .t. *循环程序组 if tc exit endifenddoon key label ctrl+ePACK DATABASE 命令将数据库所有表中作了删除标记的记录物理删除,即真正从磁盘上删除。语法PACK DATABASE说明执行该命令时,数据库必须以独占方式打开。该命令可用于在程序中定期清理数据库各表中的删除记录,因为软件可能经常要作删除,对大的表会影响运行速度,所以可以在软件中设置 set delete on,即隐去作了删除标记的记录,但这些记录并没有真正删除,但这些垃圾记录太多了也对系统不利,故可设一功能由操作人员在需要时运行此命令来清理整个数据库。SCAN.ENDSCAN 命令将记录指针由头到尾扫描一遍,每移动一次记录指针可执行一组命令。类似于循环 DO.ENDDO 或 FOR.ENDFOR,只是这是专门针对表的循环。语法SCAN 范围 FOR 条件1 WHILE 条件2 命令组 LOOP EXITENDSCAN参数描述范围:在指定范围内扫描,即不从开头扫描到最后。FOR 条件1 及 WHILE 条件2:只扫描符合条件的记录。如果不带范围和条件子句,则隐含扫描表中的全部记录。示例库存日记帐表(字段有日期、入库数、出库数,库存数),每记录一笔出入库,则计算相应的库存数并放入表中,有时意外情况可能导致库存数出错,因此需要有一功能将库存数重新计算一遍,下面这个程序就是完成这个功能:go topdqkc=库存数 &记下第一条记录的库存数skip &跳到第2条记录scan rest &只需扫描从第2条记录起的所有记录 replace 库存数 with dqkc+入库数-出库数 dqkc=库存数 &记下当前记录的库存数endscan上面这段程序与下面这段程序是等价的:go topdqkc=库存数 &记下第一条记录的库存数skip &跳到第2条记录do while .not. eof() replace 库存数 with dqkc+入库数-出库数 dqkc=库存数 &记下当前记录的库存数 skipendscan所不同的就是不用每次都 skip,系统自动移动记录指针,这样程序运行的速度快,尤其对于按条件扫描的情况就更快了,因为用 do 的话每次都要用 locate 或 continue 进行查询,速度很受影响。与这段程序也是等价的:go topdqkc=库存数 &记下第一条记录的库存数skip &跳到第2条记录for jsq=2 to reccount() replace 库存数 with dqkc+入库数-出库数 dqkc=库存数 &记下当前记录的库存数 skipendfor您喜欢用哪个呢?注意上面第三段程序中有个小问题,在 for 语句中用了 reccount() 函数,而函数都要经过运算才能得到结果,比起直接从一个变量中获取值要慢,假如只执行1次,两者相差无几,但上面是用在循环中,for 这一句可能会执行几十万次,那么就会使速度降低很多,为此可改成下面这样:.jls=reccount()for jsq=2 to jls.SET CONFIRM 命令当输入的内容填满输入区域时是否需要按回车键跳出输入区域。语法SET CONFIRM ON | OFF参数描述ON 需要按回车键。也可以按 TAB 或其它箭头键等。提示对表单上的文本框也起作用。当对于需要慎重输入的地方,可将其设置为 ON,以便让操作者在离开输入之前可再看一下所输入的内容有没有问题,如果不设置为 ON,当输入内容输入满时,光标会自动离开文本框,不利于发现错误。OFF 不需要按回车键(隐含)。SET DEFAULT 命令设置隐含的驱动器及目录。设置了隐含的路径,我们可以在程序运行打开每个隐含路径下的文件时不用再指定路径了。语法SET DEFAULT TO 路径参数说明路径:可以是符合操作系统要求的任何路径,比如:set default to d:softrsglset default to set default to .注意如果路径中带有空格,必须用引号将路径括起来,否则会出错。比如: set default to d:softrsgl 佳帆示例当我们的程序在运行时,一般我们都需要知道该程序运行所在的目录,因为往往许多数据也是放在这个目录下,我们不能指定一个绝对的路径,因为程序编好后可能拿到另一台电脑上用,其路径可能发生变化,一旦变化便找不到所需要的数据文件了,因此我们必须有一种方法获取其当前所在的路径,有一种办法是这样:cxlj=sys(5)+sys(2003)+ 这在程序编译成独立 EXE 文件时运行是对的,但在 VFP 系统中运行 PRG 程序却不对,它返回的是 VFP 所在的目录,为了解决这个问题,可采用如下程序:CXLJ=SYS(16) &获取当前运行的程序名及其所在路径FOR JSQ=1 TO LEN(CXLJ) &用一个循环找出最右边一个反斜线,将其后的程

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论