PROGRESS语言PROGRESS语言是一种非可视化的编程语言,符合4GL规范,具有高级语言的优点,可以进行条件选择(IF、WHERE)、嵌套循环(FOR)、计算(如求和、求平均)等操作,还可以直接进行打印、显示(PUT、DISPLAY),并且不区分大小写。PROGRESS源程序一般由4部分组成:全局变量定义、图形变量定义(一般是用户指定的查询选择条件)、输出数据的格式和主程序(如何利用数据库中的字段生成用户需要的正确数据)。全局变量的定义全局变量用DEFINEVARIABLE关键字定义。格式如下:DEFINEVARIABLEW1LIKE(数据格式INTEGER,CHARACTER……)DEFINEVARIALBEW2ASVARIABLE2使用AS可以直接引用已经定义好的数据格式。比如我们要把某个变量定义成和表中的字段类型一致时,可直接定义如下:DEFINEVARIALBE1AS表中定义的字段这样我们就不用再到后台数据库中去查询该字段的数据格式,提高了编程速度。如果这个变量在调用过程中也要用到,则分别定义如下://在主过程中DEFINESHAREDVARIABLEW1LIKE(数据格式INTEGER,CHARACTER……)//在调用过程中DEFINENEWSHAREDVARIABLEW1LIKE(数据格式INTEGER,CHARACTER……)变量的主要数据类型如下表所示:数据类型缺省格式示例字符型(Character)X(8)Dongnan日期型(Data)99/99/9903/02/99布尔型(Logical)Yes/NoYes浮点型(Decimal)-,9.9912.00整型(Integer)-,,.912图形变量的定义图型变量的定义主要是把已经定义好的变量在界面上显示出来。/*账户余额查询报表中部分源程序*/FORM/*显示一个FORM*//*定义一个相当于容器的框*/RECT-FRAMEATROW1COLUMN1.25RECT-FRAME-LABELATROW1COLUMN3NO-LABELVIEW-ASTEXTSIZE-PIXELS1BY1SKIP(.1)/*GUI*//*把变量entity的选择条件显示出来*/entitycolon25label‘会计单位’entity1colon50label“至”cnamecolon25label‘摘要’acccolon25label‘账户’acc1colon50label“至”subcolon25label‘分账户’sub1colon50label“至”ctrcolon25label‘成本中心’ctr1colon50label“至”begdtcolon25label‘生效日期’enddtcolon50label“至”subflagcolon25label‘汇总分账户’ccflagcolon25label‘汇总成本中心’rpt_currcolon25label‘货币’withframeaside-labelsattr-spacewidth80NO-BOXTHREE-D/*GUI*/cnamecolon25label‘摘要’第一行在窗口中的显示如下:摘要方框中是供用户输入的选择条件。报表格式的定义报表格式的定义非常简单,只要用at和to标出相对位置即可:FORM/*GUI*/header“期初借方余额”to65“期初贷方余额”to85“期间活动金额”to92“借方活动金额”to109“贷方活动金额”to128“期末借方余额”to148“期末贷方余额”to164skip“AccountDescription”at1“账户摘要”at1“---------------”at1“---------------”to85“--------------”to134“--------------”to164withSTREAM-IO/*GUI*/framephead1page-topwidth186.at和to表示数据在framephead1上的相对位置。不同之处在于,at后边的数据表示从该点开始,而to后边的数据表示到该点结束。特别要注意的是,在PROGRESS中,只能画横线,不能画竖线。数据处理对于数据的处理,本文主要介绍如何读取数据,以及在编程时需要注意的地方。我们以账户余额查询报表为例。当在数据库的表中查找数据时,使用下述语句:FOREACH(表)WHERE(条件)//对表中数据进行处理//对符合条件的每个数据进行处理END只访问表中指定的一个数据:FINDFIRSTORLAST(表)WHERE(条件)。//对表中数据进行处理END。查找条件之间用OR或者AND连接。在PROGRESS中,有两对语句FIRST和FIRST-OF、LAST和LAST-OF,这两个判断语句非常重要,常用于判断循环的开始还是结束以及循环中的分类是开始还是已经结束。FIRST(BREAK-GROUP):当前的循环是循环体的第一次循环则返回TRUE,如果不是则返回FALSE;FIRST-OF(BREAK-GROUP):当前的循环是循环中的分类的第一次循环则返回TRUE,如果不是则返回FALSE;LAST(BREAK-GROUP):当前的循环是循环体的最后循环则返回TRUE,如果不是则返回FALSE;LAST-OF(BREAK-GROUP):当前的循环是循环中的分类的最后一次循环则返回TRUE,如果不是则返回FALSE。如果程序需要处理大量的数据,可以使用调用过程。调用过程可以采用*.P或者*.I文件。它们的区别在于*.I文件是包含文件,在编译时不生成相应的*.R文件;而*.P文件生成相应的*.R文件。注意:如果在过程中多次使用到同一个表,必须定义一个BUFFER格式:DEFINEBUFFERWWLIKE(表名)WW为表的别名。如果不定义BUFFER,编译时将出现“TABLE无法辨别!”的警告。PROGRESS编程其实很简单(二)PROGRESS程序架构。PROGRESS启动应用程序,通常都是先启动一个主程序,比如mf.p,这个mf.p做一些全局变量设置,并初始化应用程序菜单。当用户执行菜单功能时,实际上是运行菜单所指定的程序!在这种模式下,PROGRESS的程序一般都不大,结构明了可读性很强,每个程序目的非常明确,但是也要遵循一定的准则,方便以后的阅读和修改。一、程序扩展名的设定。.p主程序(可直接运行,或者编译以后挂主菜单被调用).i子程序(经常使用的执行某一特定功能,或者为了使主程序易于阅读脱离出来).v验证程序.wWindows的程序(Windows版的Progress支持可视化的组件编程,组件拉一拉放一放,就自动生成.w的文件了).r编译后的程序(菜单调用时,实际上是执行.r的程序)二、程序的命名规则。主程序格式:aa+bb+cc+dd.p其中:aa---系统模块IDbb---系统功能cc---程序类型(mt-维护、iq-查询或者rp-报表等)dd---序列号子程序格式:通常是主程序a.i主程序b.i这样子//关于程序的命名,个人觉得也没必要一定要遵循特定格式,一家公司有自己固定的命名方式,容易区分即可;如果是咨询公司或者系统集成公司,则要先了解客户的命名习惯和规则;同理,下面的“程序头”。三、程序头。以注释的形式,标明尽可能多的程序相关的信息,比如:程序名(路径,不过路径一般都是企业自己规定好了)、作者、菜单号、功能(菜单标题)、创建日期、修改日志等。至于格式,也就是POSE,爱怎么摆怎么摆,清楚明了即可。但是,在同一家公司,风格应该统一。另外,关于修改日志,个人觉得最好在程序头和程序体,都明显说明一下修改的日期和原因,要点。(注释不记入程序长度,所以不要担心程序太长,:p)四、维护类程序模板。注意:为方便说明,注释暂时用“//”,但是在PORGRESS程序里是错误的哈!definevariables.{mfdtitle.i}//程序头,全局变量定义等,是标准QAD的菜单程序就请加上这个,不要问为什么formwithframea.//定义格局(包含输入输出)Mainloop:repeat:prompt-for…editing://通常这里输入主要字段(如果比如订单号,料件名称等){mfnp.i}//前后记录显示功能,常用end./*ADD/MODI/DELETE*/assignglobal…find…ifnotavailable…//新记录{mfmsg.i11}//类似mfmsg的子程序,都是信息提示类create…assign…end.Status=stline{2}.updatego-on(F5orCtrl-D)//继续维护剩余字段ifF5orCTRL-Dthendo://判断是否按了删除键,一般定义是F5或者Ctrl+Ddel-yn=yes.{mfmsg01.i111del-yn}end.End.Statusinput.五、报表类程序的模板。{mfdtitle.i}formdefinition[selectioncriteria]partcolon15part1colon40label{t001.i}effdatecolon15effdate1colon40label{t001.i}withframeaside-labelswidth80.//以上4行定义用户输入“限制报表输出”的条件,比如生效日期啊什么的repeat:ifpart1=hi_charthenpart1=“”.//如果用户不输任何东西,则默认最大字符或者最小字符,以下类似ifeffdate=low_datetheneffdate=?.ifeffdate1=hi_datetheneffdate1=?.datastatements[selectioncriteria]bcdparm=.{mfquoter.ipart}//BATCH专用,至今没用过,体会不到好处,哪位帮忙解释一下?{mfquoter.ipart1}{mfquoter.ieffdate}{mfquoter.ieffdate1}{mfselbpr.i“printer”132}//选择打印机的子程序ifpart1=“”thenpart1=hi_char.ifeffdate=?Theneffdate=low_date.ifeffdate1=?Theneffdate1=hi_date.{mfphead.iormfphead2.i}//报表头foreach…display{mfrpchk.i}or{mfrpexit..i}//报表结束end.{mfrtrail.i}or{mftr0801.i}or{mfreset.i}//报表结束、打印结束等end.六、查询类程序模板。这个比报表来得要简单些了:{mfdtitle.i}formdefinition[selectioncriteria]withframeaside-labelswidth80.repeat:datastatement[selectioncriteria]withframea.{mfselprt.i“terminal”80}foreach[selectioncriteria]display…{mfrpchk.i}(maxpage)end.{mfreset.i}(scrolloutput){mfmsg.i81}end.这里先写一些常用命令:让大家见笑了。createupdate/setinsertdisplayrepeat...endforeach...enddeleteprompt-for须与input匹配findfirst(last)where.....=input.....与using等同inputwithncolumn,withno-lable,no-error,notavailableexceptassignmessageif............then...........elsedefinevariablelabel...........EQ就是=的意思begin