RPG AS400程序员培训手册.docx
- 文档编号:6624641
- 上传时间:2023-05-10
- 格式:DOCX
- 页数:22
- 大小:26.66KB
RPG AS400程序员培训手册.docx
《RPG AS400程序员培训手册.docx》由会员分享,可在线阅读,更多相关《RPG AS400程序员培训手册.docx(22页珍藏版)》请在冰点文库上搜索。
RPGAS400程序员培训手册
2.8.4.4O--R
ON-ERROR(On-Error)
没用过
OPEN{(E)}(OpenFileforProcessing)打开文件
Factory1OperationFactory2ResultHILOEQ
OPEN文件名
OPEN后面的目标,必须是在当前程序中已声明的文件名(不是文件的记录格式名),
而且在OPEN操作之后,在程序结束之前之前,必须有对应的CLOSE操作。
使用OPEN操作,文件在声明时,必须使用USROPN关键字(详见D行说明)。
ORxx(Or)逻辑判断—或
Factory1OperationFactory2ResultHILOEQ
FLD01IFGTFLD03
FLD01OREQFLD02
等价于
IFFLD01>FLD03ORFLD01=FLD02
与IF、IFxx,AND、ANDxx类似,RPGLE的写法OR,比RPG的写法ORxx要灵活,
而且可以用来表达一些复杂的逻辑关系。
有鉴于此,所以通常IF语句中,我会以OR为主,
基本不用ORxx。
如果在编程序方面,公司/项目组无硬性要求,那我觉得还是少用ORxx吧,
总觉得这种写法的逻辑关系看起来不直接,尤其是有很复杂的AND,OR时。
OTHER(OtherwiseSelect)分支语句的判断
与分支语句SELECT一起使用,表示不符合上述所有条件时的操作,如下:
Factory1OperationFactory2ResultHILOEQ
SELECT
WHEN条件判断1
处理语句1
WHEN条件判断2
处理语句2
OTHER
处理语句3
ENDSL
在这个例子中,当满足条件判断1时,运行处理语句1,运行结束后跳至ENDSL处;
如果不满足条件判断1,则程序继续向下执行,判断是否满足条件判断2。
当满足条件判断2时,运行处理语句2,跳至ENDSL;当不满足
当不满足条件判断2时,程序继续向下执下,当读到OTHER操作码时,无条件运
行处理语句3(即当程序当前不满足以上所以条件判断时,则执行OTHER之后的语句。
处理语句允许有很多句;
条件判断可以写得很复杂,也允许对不同的字段进行判断;比如说C语言也有分支语
句switch,但是这个语句只能对一个字段进行分支判断,ILE语言与它不同,允许对不同的
字段进行判断
就我目前掌握的测试情况,上述的SELECT—WHEN--OTHER—ENDSL,其实也可以
写做:
IF条件判断1
处理语句1
ELSEIF条件判断2
处理语句2
ELSE
处理语句3
ENDIF
即WHEN与ELSEIF是类似的,这样说,应该可以明白了吧。
总之,SELECT—ENDSL是一个很好用的语法,尤其是在表示很多不同的分支处理时。
OUT{(E)}(WriteaDataArea)
没用过,讲数据域的。
PARM(IdentifyParameters)定义入口参数
Factory1OperationFactory2ResultHILOEQR
*ENTRYPLIST
PARMFLD01
关于具体内容讲解,详见前面所说“入口参数”一章。
允许做为入口参数的有:
普通变量、结构变量、数组变量
关于PARM、PLIST,还有一种在Factory1,Factory2也填写变量或指示器的用
法,不过我不知道它具体表示什么意思,也不知道该怎么用。
请用过的来补充。
PLIST(IdentifyaParameterList)同上
POST{(E)}(Post)
没用过
READ{(N|E)}(ReadaRecord)读取记录
1.基本语法:
Factory1OperationFactory2ResultHILOEQ
READ文件记录格式名4546
READ后面跟的,必须是声明的文件记录格式名;
LO指示器表示锁表指示器,当在指定的时间(CHGPF,WAITRCD项可看到),
需要读取的记录仍被锁,将会打开LO指示器,即*IN45=’1’;
EQ指示器为是否读到指示器。
当未读到任何记录时,打开EQ指示器,即*IN46=’1’
2.当文件在程序中,是用只读的方式声明时,READ操作并不会造成锁表;
如果文件在程序中是用修改的方式声明,READ操作成功后,该记录被锁;直到执
行解锁操作(UNLOCK,或UPDATE),或READ该文件的其它记录,才会解锁
如果文件是用修改的方式声明,但希望READ操作不锁表时,那么就用READ(N),
即
Factory1OperationFactory2ResultHILOEQ
READ(N)文件记录格式名4546
这样读文件,就不会锁记录,但是同时也不能修改记录。
如果需要修改记录,那么
在修改之前(包括对文件字段赋值之前),还必须再对该记录进行一次定位操作(比如
CHAIN、READ语句均可)。
也就是说,如果要修改记录,必须先锁住当前记录(很合
理吧)
3.当执行READ操作时,程序是根据游标当前在文件中所指向的位置,顺序读取下
一条记录。
关于游标是如何指向,还不是一个很简单的问题,所以将会在下一章“数
据库相关知识”中具体讲解。
4.执行READ操作时,允许声明的文件没有键值。
(即PF文件)
READC{(E)}(ReadNextChangedRecord)
没用过,读下一次修改过的记录?
READE{(N|E)}(ReadEqualKey)读取键值相等的记录
语法与READ操作码大致一样,这里不再重复,只说不同的:
假设程序中已声明逻辑文件PFFHSL3(键值为FHS01+FHS02)
Factory1OperationFactory2ResultHILOEQ
FHSKEYKLIST
KFLDFLD01
KFLDFLD02
FHSKEYSETLLFMTFHS
DOW1=1
FHSKEYREADEFMTFHS15
IF*IN15=’1’
LEAVE
ENDIF
ENDDO
这段话的意思,就是定义组合键值FHSKEY,然后根据这个FHSKEY在逻辑文件
PFFHSL3中去定位,循环读取PFFHSL3中,FHS01、FHS03与FLD01、FLD02相等的记
录。
当读取记录结束,或键值不等时,退出循环(*IN15是EQ指示器)。
如果将READE操
作码换成READ操作码的话(当然,Factory1处也就不能有值),就没有“键值不等时退出
循环”这一层意思,只是读不到记录时就退出循环,但有时我们使用逻辑文件,仅仅是需要
它的排序,而不需要读不到键值相等的记录就退出循环。
所以说,使用READ操作码,还
是READE操作码,需要根据实际的要求来决定。
以上的Factory1处填写值的系统处理,当READE操作码在Factory1处未填写值时,
系统实际上是将当前的值与读到的上一条记录的关键字进行比较,而不是与SETLL时的键
值做比较(读第一条记录不做比较!
),如果键值不等时,置EQ指示器为1。
。
也就是说,
如果没有与FHSKEY键值相同的录,那么系统并不是直接找开EQ指示器,而是会一直保
持正常地往下读,直到找到与读到的第一条记录关键字不同的记录,才会打开EQ指示器,
所以要注意。
READP{(N|E)}(ReadPriorRecord)读取记录—游标上移
简单来说,READ、READE操作时,游标在数据文件中,是下移的;即读完第一条记
录,游标指向第二条记录;读完第二条记录,游标指向第三条记录,依此类推,直至最后一
条记录。
但READP则正好相反,游标是上移的,即读完第三条记录后,游标指向第二条记
录;读完第二条记录后,游标指向第一条记录,直至读完第一条记录。
一般来说,用READ、READE的概率会比READP、READPE的概率高得多,不过在
某些情况下,使用READP操作,又的确会很省事,这个一时间想不起例子来,大家可在编
程序时多实践。
READPE{(N|E)}(ReadPriorEqual)
虽然我没用过,但猜想它应该就是指游标上移,按键值去读取文件。
与READP的关系,
就类似于READE与READ的关系。
REALLOC{(E)}(Re-allocateStorage)
没用过
REL{(E)}(Release)
没用过
RESET{(E)}(Reset)
将数据结构赋值成为初始值。
注意是初始值,不是清空。
如定义结构:
DFHSDSDS
DFHS0110INZ(’ABCD’)
DFHS025INZ(’EFGH’)
那么,不管对该结构如何赋值,当执行语句:
CRESETFHSDS
之后,FHS01将会变成’ABCD,FHS02将会变成’EFGH’,即恢复成为初始值。
RETURN{(H|M|R)}(ReturntoCaller)
RETURN是程序结束。
在前面,“简单的程序流程”中,我们讲过,“SETONLR”与RETURN这两句话一
起,做为程序的结束。
这里,再详细解释一下两者之间的区别,以及关系:
如果不写RETURN,只写“SETONLR”,程序执行完最后一句之后,将会再从第一
句开始执行,造成死循环。
在简单的程序流程这个例子中,程序原来只想修改读到的第一条
记录,而如果没有RETURN的话,将会把所有的记录都修改掉,直到最后找不到可修改的
记录,然后系统报错,异常中断。
(这种离奇的现象现在又测试不到了,可能是当时写错程
序了?
把F写成了P?
不管它,当是我写错了,总之RETURN是表示程序结束,没有
RETURN,主程序无可执行的语句时,它也会结束;如果RETURN出现在主程序的中间,
那么RETURN后面的语句将不会执行)
如果只写RETURN,不打开指示器*INLR,根据blogliou所说“程序不会强制将内存
中的数据写到磁盘中。
400缺省的是BLOCK输出,即数据记录满一个BLOCK块时才会将
这一组记录写到磁盘上。
那么如果这时BLOCK没满,数据信息不会立刻写到磁盘上。
之后
有其它作业用到该文件,读取的数据就不完整。
”
但如果文件有唯一键字,或记录日志,必须同步写时,其实BLOCK实际被忽略,也就
是此时不会有错。
目前我们用的是MIMIX备份,客户实际上将所有的文件都列入日志,这
时不写也不会出现上述错误。
但为避免一些潜在的问题,养成良好的编程风格,建议将
SETONLR与RETURN一同,做为程序结束的标志。
当然,如果某个程序频繁被调用,且
不涉及文操作时,可考虑不打开指示器*INLR,仅用RETURN作为结束,这样程序不
会被PURGE出内存,可提高调用效率。
如果没写RETURN,也没有打开指示器*INLR,在编译时,系统将会报40级错,说找
不到程序结束的语句,所以大可放心。
ROLBK{(E)}(RollBack)
1.基本语法
Factory1OperationFactory2Result
ROLBK
2.该操作码无其它参数,就是指对事务处理进行回滚操作。
3.ILE程序中,ROLBK操作可随时进行,也允许在没有声明COMMIT类型的文件
的情况下,仍进行ROLBK操作(对该进程这前的事务进行确认处理)f
4.关于日志的确认回滚操作,在后面会另设专门章节讲述。
2.8.4.5S--Z
SCAN{(E)}(ScanCharacterString)扫描字符串
扫描字符或字符串Factory1在目标字符串Factory2中是否存在
Factory1OperationFactory2ResultHILOEQ
FLD01SCANFLD02N26
FLD01可以是字符,也可以是字符变量;可以是一位长,也可以是多位长。
当FLD01在FLD02中存在时,EQ指示器打开,即*IN26=’1’,同时将FLD02中的起始
位置,赋值给N;
当FLD01在FLD02中不存在时,EQ指示器保持关闭状态,即*IN26=’0’,同时N=0
允许从FLD02中的指定位置开始检查:
FLD01SCANFLD02:
2N26
如上句,即表示从FLD02的第2位,开始扫描。
在实际使用中,比如说我们判断某个字符是否为数字,就可以先定义一个0—9的常量,
然后将要判断的字符去SCAN一下这个常量
SELECT(BeginaSelectGroup)分支语句
在操作码“OTHER”中讲过,为方便读者,列出简单语法如下:
Factory1OperationFactory2ResultHILOEQ
SELECT
WHEN条件判断1
处理语句1
WHEN条件判断2
处理语句2
OTHER
处理语句3
ENDSL
要注意,SELECT操作码,必须有对应的ENDSL操作码,否则编译无法通过。
SETGT{(E)}(SetGreaterThan)定位操作—大于
举个例子吧,假设文件中有一个字段,是标识顺序号的,1、2、3、4。
即该字段为1,
表示第一条记录,该字段为2,表示第2条记录。
那么:
Factory1OperationFactory2ResultHILOEQ
2SETGT文件记录格式名
READ文件记录格式名
这个READ操作,READ到的,是第3条记录。
也就是说,SETGT操作码,会将游标
定位到大于键值的第一条记录前。
在实际使用中,如果我们是按逻辑文件读取,而且读了一条记录之后,对其键值相同的
记录都不需要再读取时,就可以用SETGT,不过需要注意,Factory1项,需要是与键值相
同的变量,即如果文件是使用多个字段做为键值,那么我们也需要先定义一个组合键值的变
量,然后Factory1处填写这个组合键值的变量名。
当声明文件的键值有多项时,Factory1项的键值,允许小于文件的键值,但顺序必须
一致。
即声明的文件如果键值为:
FHS01、FHS02、FHS03,那么我们在程序中定义三个类
型与之相同的变量FLD01、FLD02、FLD03,以下写法都是有效的
FLDKEYKLIST
KFLDFLD01
KFLDFLD02
KFLDFLD03
FLDKEYSETGT文件记录格式名
FLDKEYKLIST
KFLDFLD01
KFLDFLD02
FLDKEYSETGT文件记录格式名
FLD01SETLL文件记录格式名
SETLL{(E)}(SetLowerLimit)定位操作—小于
语法与SETGT相同,含义与SETGT不同。
SETLL操作码,会将游标定位到与键值相
等的第一条记录之前,仍是上例,如果是
2SETLL文件记录格式名
READ文件记录格式名
那么READ操作码读到的记录,就是第2条记录,看到了吧,和SETGT不同。
SETLL操作码还可以用来简单判断当前键值是否存在有记录,以PFFHSL3为例(键值
为FHS01、FHS02)
Factory1OperationFactory2ResultHILOEQ
FHSKEYKLIST
KFLDFLD01
KFLDFLD02
EVALFLD01=’01’
EVALFLD02=’02’
FHSKEYSETLL文件记录格式名44
当文件中有相应记录时,EQ指示器打开,即*IN44=’1’
当文件中无相应记录时,EQ指示器关闭,即*IN44=’0’(与CHAIN正好相反,要注意)
而在这种用法中,SETLL与CHAIN的区别在于,CHAIN是定位读取了记录,而SETLL
仅仅只是判断该记录是否存在。
所以用SETLL操作,不能修改记录,也无法取出记录的值。
只能判断记录是否存在。
如果要修改记录,或取出记录的值,还需要有一个读取定位的操作,
如READ,或READE、READP等(最常用的,应该就是READ操作)
SETOFF(SetIndicatorOff)关闭指示器
Factory1OperationFactory2ResultHILOEQ
SETOFF101112
等价于
EVAL*IN10=’0’
EVAL*IN11=’0’
EVAL*IN12=’0’
在SETOFF这个操作码中,指示器填在HI、LO、EQ哪里都没关系,都是表示要被关
闭的指示器
SETON(SetIndicatorOn)打开指示器
Factory1OperationFactory2ResultHILOEQ
SETOFF101112
等价于
EVAL*IN10=’1’
EVAL*IN11=’1’
EVAL*IN12=’1’
在SETON这个操作码中,指示器填在HI、LO、EQ哪里都没关系,都是表示要被关闭
的指示器
SHTDN(ShutDown)
没用过
SORTA(SortanArray)
没用过
SQRT{(H)}(SquareRoot)开方
Factory1OperationFactory2ResultHILOEQ
9SQRT3N
这时,N=3(因为3的平方为9)
9、3都可以是数字型变量,或者直接是数字
SUB{(H)}(Subtract)减法操作
Factory1OperationFactory2ResultHILOEQ
FLD01SUBFLD02FLD03
SUBFLD02FLD03
看过前面的ADD、MULT操作码,这里不用解释也应该明白是什么意思了吧。
那就不
多说了。
SUBDUR{(E)}(SubtractDuration)日期相减
1.减日期
Factory1OperationFactory2ResultHILOEQ
FLD01SUBDURN:
*YFLD02
表示将日期型变量FLD01减去N年,赋值到日期型变量FLD02中;
N可以是一个数字型变量,也可以就是一个数字,N允许为负数
*Y,*M,*D(还有其它的参数值,可见ADDDUR,其中有详细解释)
2.判断两个日期型变量之间的天/月/年数
Factory1OperationFactory2ResultHILOEQ
FLD01SUBDURFLD02N:
*D
这时,N做为一结果变量,表示日期型变量FLD01与FLD02之间的天数
SUBST{(P|E)}(Substring)取字符/字符串
Factory1OperationFactory2ResultHILOEQ
2SUBSTFLD01:
3FLD02
表示从字段FLD01的第3位开始,取2位,左对齐赋值到字段FLD02中。
要求字段FLD01的长度必须大于或等于3+2位,否则程序会报错。
可以尝试用%SUBST语句,也是等价的,如下
EVALFLD02=%SUBST(FLD01:
3:
2)
表示的是同样的意思。
起始位数3,取的长度2,在两种写法之下,都可以使用数字型变量来表达。
相比较之下,%SUBST还有一种用法,就是对字符的指定位置赋值,这个就厉害了:
EVAL%SUBST(FLD02:
3:
2)=’01’
看到了吧,这句话就是说,使字段FLD02的第3、4位(即从第三位开始,两位长)等
于“01”
TAG(Tag)定义标签,与GOTO同用
Factory1OperationFactory2ResultHILOEQ
FHSTAGTAG
TEST{(D|T|Z|E)}(TestDate/Time/Timestamp)
没用过
TESTB(TestBit)
没用过
TESTN(TestNumeric)
没用过
TESTZ(TestZone)
没用过
TIME(TimeofDay)--取当前系统时间
Factory1OperationFactory2ResultHILOEQ
TIMEFLD01
FLD01可以是时间型或数字型变量
UNLOCK{(E)}(UnlockaDataAreaorReleaseaRecord)解锁
Factory1OperationFactory2ResultHILOEQ
UNLOCK文件记录格式名
UNLOCK是解锁操作,在某种程度上,可以将UNLOCK视为ROLBK,将UPDATE
视为COMMIT。
即如果锁定某条记录,并对其字段进行赋值之后,使用UPDATE语句,将
会把修改后的结果保存下来,即修改文件,而UNLOCK语句则不会修改文件,即否认了之
前对文件字段做的赋值修改。
从程序的执行效率上来讲,UNLOCK的执行效率是高于UPDATE的,因为UPDATE
操作时,系统需要对文件的每一个字段进行确认处理(DEBUG时可以看到),而UNLOCK就
是简单的解锁而已。
UPDATE(ModifyExistingRecord)修改记录
语法与UNLOCK一样。
这里需要说明一下,在执行UPDATE的时候,必须先使用READ、CHAIN等操作码锁
定一条记录。
如果未锁住记录,UPDATE操作码将会报错。
当执行了UNLOCK、UPDATE、
以及ROLBK语句时,等于是解锁,此时再执行UPDATE操作码之前,必须再次锁住记录
操作;
WHEN{(M|R)}(When)分支判断语句中的条件判断
在操作码“OTHER”,“SELECT”中都讲过,仍列出简单语法如下:
Factory1OperationFactory2ResultHILOEQ
SELECT
WHEN条件判断1
处理语句
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- RPG AS400程序员培训手册 AS400 程序员 培训 手册