PROGRESS入门基础

PROGRESS
入門基礎

PROGRESS编程(一)

一、变量定义。

变量必须在第一次被使用之前定义,可以定义在程序的任何地方!但是通常为了增加程序的可读性,变量定义都放在程序的开始处!以下是变量定义的几个实例:

define variable str01 as string label “DemoString” initial “hello”.
def var str02 like str01.
def var dt01 as date extent 5.
def var inte01 as inte format “>>>9”.

说明,第一行:
str01 是变量名, 变量名不要与系统关键字重复,字符或者下划线开头,比如strModel,_Model ;
string 表示变量类型,本例指字符型变量,其它类似的比如integer,date,logical等 ;
label 就是后续程序中对变量的描述,比如需要用户输入这个变量值时,系统提示“DemoString" ;
initial 变量的初始值
第二行:
def和var都是简写,def是define的简写,var是variable的简写;PROGRESS支持语法简写,但是初学者最好先写全,后面有经验了再简写。
like和as的不同点是:as后面直接说明变量类型,而like后面跟另外一个变量或者字段。
第三行:
extent 5 ,表示该变量是数组变量。
第四行:
format “>>>9” 变量格式
指定变量的格式一个最大的好处就是预留宽度,这个对变量的输入或者报表的输出都很有用的。
比如年份的宽度一定是4位的,那么你就可以指定格式 format “9999”。

PROGRESS程序每行结束必须有个“.”号!!!

二、注释。

注释就是用 ,可以嵌套,比如

—*/

三、记录的显示。

如果进入PROGRESS编程模式以后连接了数据库,那么直接显示记录的值即可,比如:
for each TABLE_NAME:
display TABLE_NAME.
end.

或者:
find first TABLE_NAME.
display TABLE_NAME.

通常显示记录值都是采用这2种方式!当然,可以按要求显示特殊的字段,比如:
for each pt_mstr where pt_model begins “E” no-lock break by pt_price:
disp pt_model pt_price.
end.
这个程序看起来真的很容易明白,简单说明:
1、where 后面带条件,比如 = <> <= >= 等等,这种关系符,对数字、日期或者字符串,都适用;
关于条件的几种组合举例:
条件1 and 条件2
( 条件1 or 条件2)and (条件3 or 条件4)
not 条件1
2、no-lock,这是关键字,你只要记住:
如果接下来的程序要对记录进行修改,那么不能加no-lock,如果不要,请加上no-lock;
3、break by ,就是按某个字段排列,默认是按这个字段的升序,如果降序则后面加上 desc,比如:
break by pt_price desc。
如果需要多次排列,那么by几次就可以,比如:
break by pt_price by pt_date

另外一个常用的显示或者更新记录的语句是find!比如:
find pt_mstr where pt_model = “mainboard” no-lock no-error.
find first pt_mstr where pt_price <= 10 no-error.
find last pt_mstr where pt_price <= 10 no-error.
说明:
1、where后面的条件跟for each语句类似;
2、no-lock的作用跟for each的no-lock也是一样的;
3、no-error,通常是find就加上,否则如果找不到满足条件的记录,系统会出错误提示;而实际上,通常需要在程序自己判断结果;
4、find first 就是定位第一天满足条件的记录;find last 定位最后一条满足条件的记录;
4、还有一种叫find next,就是定位当前记录的下一条;
5、find 和 find first / find last 不同的是,find后面带的条件,通常是满足TABLE的某个唯一索引。

关于for each 和 find,这章你只要了解到这里就OK了!

四、判断。

判断最简单了,就是一个if 条件 then … else …,比如:
if str01 = “cpu” then disp “CPU”
else disp “Not CPU”.
当然,这个”条件“可能有很复杂的组合。如果,涉及到的动作比较多,那么做法是用do: … end.,比如
if str01 = “cpu” then do:
str01 = “my cpu”.
disp “CPU”.
end.
else do:
str01 = “my memory”.
disp “Not CPU”.
end.
if 支持嵌套,怎么嵌套?你自己会了!不是吗?

五、循环。

PROGRESS的循环功能实在令人不敢恭维,没有when 没有while,没有loop、for什么的,只有一个repeat!
不过,用好了这个repeat,一样实现任何功能。
通常实现循环的模式:
repeat:

  if 条件 then leave.

end.
现在,你试试用find 和 repeat 实现 for each的功能!

六、赋值和计算。

+ - * / ,就是 加 减 乘 除了!比如:
ttl_amoount = ttl_ammount + dtl_amount.
x_a = x_b / x_c.
str_ttl = “I’m” + “sure!”.
dt01 = today - 1.
dt01 = 3/22/2005.
当然,日期和字符串不能做乘法或者除法!

七、其它零星的语法。

显示:display 简写disp
退出编程模式:quit
执行UNIX命令: unix COMMAND

好了,这章你学会了,如果熟悉数据库表和字段的结构,你也大概能看任何东西了,甚至做一些常规的统计也肯定没问题!

PROGRESS编程(二)

PROGRESS程序架构。

PROGRESS启动应用程序,通常都是先启动一个主程序,比如mf.p,这个mf.p做一些全局变量设置,并初始化应用程序菜单。当用户执行菜单功能时,实际上是运行菜单所指定的程序!在这种模式下,PROGRESS的程序一般都不大,结构明了可读性很强,每个程序目的非常明确,但是也要遵循一定的准则,方便以后的阅读和修改。

一、程序扩展名的设定。

.p 主程序(可直接运行,或者编译以后挂主菜单被调用)
.i 子程序(经常使用的执行某一特定功能,或者为了使主程序易于阅读脱离出来)
.v 验证程序
.w Windows的程序(Windows版的Progress支持可视化的组件编程,组件拉一拉放一放,就自动生成.w的文件了)
.r 编译后的程序(菜单调用时,实际上是执行.r的程序)

二、程序的命名规则。
主程序格式: aa + bb + cc + dd.p
其中:
aa — 系统模块ID
bb — 系统功能
cc — 程序类型(mt -维护、iq -查询或者rp -报表等)
dd — 序列号
子程序格式:通常是 主程序a.i 主程序b.i 这样子
//关于程序的命名,个人觉得也没必要一定要遵循特定格式,一家公司有自己固定的命名方式,容易区分即可;如果是咨询公司或者系统集成公司,则要先了解客户的命名习惯和规则;同理,下面的“程序头”。

三、程序头。
以注释的形式,标明尽可能多的程序相关的信息,比如:程序名(路径,不过路径一般都是企业自己规定好了)、作者、菜单号、功能(菜单标题)、创建日期、修改日志等。至于格式,也就是POSE,爱怎么摆怎么摆,清楚明了即可。但是,在同一家公司,风格应该统一。另外,关于修改日志,个人觉得最好在程序头和程序体,都明显说明一下修改的日期和原因,要点。(注释不记入程序长度,所以不要担心程序太长,:p )

四、维护类程序模板。

注意:为方便说明,注释暂时用“//”,但是在PORGRESS程序里是错误的哈!
define variables.
{mfdtitle.i} //程序头,全局变量定义等,是标准QAD的菜单程序就请加上这个,不要问为什么
form with frame a. //定义格局(包含输入输出)
Mainloop:
repeat:
prompt-for … editing: //通常这里输入主要字段(如果比如订单号,料件名称等)
{mfnp.i} //前后记录显示功能,常用
end.

    assign global…
    find …
    if not available … //新记录
        {mfmsg.i 1 1} //类似mfmsg的子程序,都是信息提示类
        create …
        assign …
    end.
    Status = stline{2}.
    update go-on (F5 or Ctrl-D)  //继续维护剩余字段
    if F5 or CTRL-D then do: //判断是否按了删除键,一般定义是F5或者Ctrl + D
        del-yn = yes.
        {mfmsg01.i 11 1 del-yn}
    end.

End.
Status input.

五、报表类程序的模板。

{mfdtitle.i}
form definition [selection criteria]
part colon 15 part1 colon 40 label {t001.i}
effdate colon 15 effdate1 colon 40 label {t001.i}
with frame a side-labels width 80.
//以上4行定义用户输入“限制报表输出”的条件,比如生效日期啊什么的
repeat:
if part1 = hi_char then part1 = “”. //如果用户不输任何东西,则默认最大字符或者最小字符,以下类似
if effdate = low_date then effdate = ?.
if effdate1 = hi_date then effdate1 = ?.
data statements [selection criteria]
bcdparm = “”.
{mfquoter.i part } //BATCH专用,至今没用过,体会不到好处,哪位帮忙解释一下?
{mfquoter.i part1 }
{mfquoter.i effdate}
{mfquoter.i effdate1 }
{mfselbpr.i “printer” 132} //选择打印机的子程序
if part1 = “” then part1 = hi_char.
if effdate = ? Then effdate = low_date.
if effdate1 = ? Then effdate1 = hi_date.
{mfphead.i or mfphead2.i} //报表头
for each…
display
{mfrpchk.i} or {mfrpexit…i} //报表结束
end.
{mfrtrail.i} or {mftr0801.i} or {mfreset.i} //报表结束、打印结束等
end.

六、查询类程序模板。

这个比报表来得要简单些了:
{mfdtitle.i}
form definition [selection criteria]
with frame a side-labels width 80.
repeat:
data statement [selection criteria] with frame a.
{mfselprt.i “terminal” 80 }
for each [selection criteria]
display …
{mfrpchk.i} (max page)
end.
{mfreset.i} (scroll output)
{mfmsg.i 8 1}
end.

通过这章的学习,你对QAD的PROGRESS程序已经有大致的了解。但是你可能还是感觉到,如果叫你做一些切实的东西,还摸不着门(什么?你摸得着了,那么恭喜你,你可以请我吃饭了),没关系,才2小时呢,25%的课程而已,不急不急!

PROGRESS编程其实很简单(三)

这章,重点解释PROGRESS报表的精髓 first-of() & last-of() 。

首先给出本章教程用到的示例信息—demo表的结构和数据。
因为测试环境只连接了一个数据库,所以本文所有对字段的引用都直接写出来而没有特别指明表名,如果是多数据库环境,则需要带表名。
(比如数据库名是dtbl,表名是demo,那么对字段的引用应该是:dtbl.demo.mdlno)
【结构】

【数据】

1、first-of() & last-of()的语法;
先看示例:
for each demo break by demo.vend:
if first-of(demo.vend) then disp demo.vend.
end.

很明显可以看出来的就是,每个first-of或者last-of对应的字段,必须有for each … break by来对应它,否则语法错误(即使first-of的字段是索引也会出错)。
比如以下语句会出错:
for each demo no-lock:
if first-of(demo.vend) then disp demo.vend.
end.

2、函数的功能;
first-of()函数的功能,就是通过break by 对该字段进行排序,然后对该字段相同的记录进行“预览”,当第一次出现时发生!比如,示例中,break by首先对demo.vend进行排序,这样会出现很多vend是“hp”和“ibm”的记录,当第一次出现“hp”记录和第一次出现“ibm”记录时,各显示一下该vend名称。
last-of()一样,不同的是“最后一次出现时发生”!
请看示例:
for each demo break by demo.mdlno:
if last-of(demo.mdlno) then disp demo.
end.

这段程序的结果如下:

通过收货日期和数量等,可以看到,每条记录,都是相同“mdlno”的最后一条

3、应用;
通过以上分析,不知道大家有没有懂的真正的意思呢?
现在如果要实现这样的报表,那又该怎么写程序呢?
对每个mdlno收货进行合计,然后在mdlno的下一行显示合计数,类似这样的结果:

不看答案自己想想看。

参考答案(为方便阅读暂不用accum()函数):
DEF VAR ttl AS DECI.

OUTPUT TO c:\demoout.txt.
FOR EACH demo BREAK BY demo.mdlno:
ttl = ttl + demo.qty.
PUT demo.mdlno demo.rcvdt demo.qty SKIP .
IF LAST-OF(demo.mdlno) THEN do:
PUT " 合计" ttl SKIP.
ttl = 0.
END.
END.
OUTPUT CLOSE.

说明:first-of 和 last-of 可以对应多个 break by的字段,比如可以先按mdlno汇总,再按 vendor汇总!

[转]PROGRESS资料3
PROGRESS语言
PROGRESS语言是一种非可视化的编程语言,符合4GL规范,具有高级语言的优点,可以进行条件选择(IF、Where)、嵌套循环(FOR)、计算(如求和、求平均)等操作,还可以直接进行打印、显示(PUT、DISPLAY),并且不区分大小写。
PROGRESS源程序一般由4部分组成:全局变量定义、图形变量定义(一般是用户指定的查询选择条件)、输出数据的格式和主程序(如何利用数据库中的字段生成用户需要的正确数据)。
全局变量的定义
全局变量用DEFINE VARIABLE 关键字定义。格式如下:
DEFINE VARIABLE W1 LIKE(数据格式INTEGER,CHARACTER……)
DEFINE VARIALBE W2 AS VARIABLE2
使用AS可以直接引用已经定义好的数据格式。比如我们要把某个变量定义成和表中的字段类型一致时,可直接定义如下:
DEFINE VARIALBE1 AS 表中定义的字段
这样我们就不用再到后台数据库中去查询该字段的数据格式,提高了编程速度。如果这个变量在调用过程中也要用到,则分别定义如下:
//在主过程中
DEFINE SHARED VARIABLE W1 LIKE (数据格式INTEGER,CHARACTER……)
//在调用过程中
DEFINE NEW SHARED VARIABLE W1 LIKE (数据格式INTEGER,CHARACTER……)
变量的主要数据类型如下表所示:
数据类型 缺省格式 示例
字符型(Character) X(8) Dongnan
日期型(Data) 99/99/99 03/02/99
布尔型(Logical) Yes/No Yes
浮点型(Decimal) ->>,>>9.99 12.00
整型(Integer) ->,>>>,>>.9 12

图形变量的定义
图型变量的定义主要是把已经定义好的变量在界面上显示出来。
/*账户余额查询报表中部分源程序*/
FORM /* 显示一个FORM */
/* 定义一个相当于容器的框 */
RECT-FRAME AT ROW 1 COLUMN 1.25
RECT-FRAME-LABEL AT ROW 1 COLUMN 3 NO-LABEL VIEW-AS TEXT SIZE-PIXELS 1 BY 1
SKIP(.1) /*GUI*/
/* 把变量entity的选择条件显示出来*/
entity colon 25 label ‘会计单位’ entity1 colon 50 label “至”
cname colon 25 label‘摘要’
acc colon 25 label ‘账户’acc1 colon 50 label “至”
sub colon 25 label ‘分账户’ sub1 colon 50 label “至”
ctr colon 25 label ‘成本中心’ ctr1 colon 50 label “至”
begdt colon 25 label ‘生效日期’ enddt colon 50 label “至”
subflag colon 25 label ‘汇总分账户’
ccflag colon 25 label ‘汇总成本中心’
rpt_curr colon 25 label ‘货币’
with frame a side-labels attr-space width 80
NO-BOX THREE-D /*GUI*/
cname colon 25 label ‘摘要’
第一行在窗口中的显示如下:
摘要
方框中是供用户输入的选择条件。
报表格式的定义
报表格式的定义非常简单,只要用at和to标出相对位置即可:
FORM /*GUI*/ header
“期初借方余额” to 65
“期初贷方余额” to 85
“期间活动金额” to 92
“借方活动金额” to 109
“贷方活动金额” to 128
“期末借方余额” to 148
“期末贷方余额” to 164 skip
“Account Description” at 1
“账户 摘要 ” at 1
“--------------- ” at 1
“---------------” to 85
“-------------- ” to 134
“-------------- ” to 164
with STREAM-IO /*GUI*/ frame phead1 page-top width 186.
at和to 表示数据在frame phead1 上的相对位置。不同之处在于,at后边的数据表示从该点开始,而to后边的数据表示到该点结束。特别要注意的是,在PROGRESS中,只能画横线,不能画竖线。
数据处理
对于数据的处理,本文主要介绍如何读取数据,以及在编程时需要注意的地方。
我们以账户余额查询报表为例。当在数据库的表中查找数据时,使用下述语句:
FOR EACH (表) Where (条件)
//对表中数据进行处理
//对符合条件的每个数据进行处理
END
只访问表中指定的一个数据:
FIND FIRST or LAST (表) 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格式:
DEFINE BUFFER WW LIKE (表名)
WW为表的别名。如果不定义BUFFER,编译时将出现“TABLE 无法辨别!”的警告。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值