1. PF
假设文件名字为BAE
A R BAER //记录名字
A AREA 3 COLHDG('AREA CODE') //field
A AREANM 22 COLHDG('AREA DESC') //field
DDS格式:
数据类型:
2. LF
LF的文件记录格式必须与PF中的文件记录格式一样,否则编译会报错。
A R BAER //记录名字
A PFILE(BAE) //LF引用的是BAE文件
A K AREA //搜索关键字是AREA CODE
复杂的:
A R BAER //记录名字
A PFILE(BAE) //LF引用的是BAE文件
A K AREANM //搜索关键字是AREA DESC
A S AREA COMP(EQ '001') //S表示选择,COMP表示比较,EQ表示等于,含义为只选择AREA等于001的那些记录(EQ、NE、GE、LE、GT、LT)
注意:如果一个PF每个库里面都有,如何确保被引用的就是自己希望的那个?将目标文件放在位于库列表的最上面的库里面。
FLFTEST UF A E K DISK
编写逻辑文件时,指定字段与不指定字段:
在定义 LF 时,可以不指定字段,只指定键值,这样的话,默认LF 文件中继承PF 文件中的所有字段,如:
A R FMTFHS PFILE(PFFHS)
A K FHS01
也可以指定字段名(写法与编写 PF 文件相同),如下:
A R FMTFHS PFILE(PFFHS)
A FHS01
A FHS02
A K FHS01
这样的话,这个LF 将会只包含指定的字段名,在上例中,也就是LF 文件中将不包含字段FHS03。访问FHS03时编译会报错。
指定唯一键值:
A UNIQUE
A R FMTFHS PFILE(PFFHS)
A K FHS01
则表示在整个物理文件PFFHS 中,FHS01 的值必须唯一。如果唯一键指向了多个字段,则表示这几个字段联合起来是惟一的,即只要不是所有键都相同即可。
3. PGB之 F行具体操作:
F行在最前面,D在中间,C行在最后。
(1) 只从文件中读取记录
FFILENAME IF E(表示外部文件) K(对于LF文件生效,表示按键值查询) DISK
(2) 只向文件里面写记录而不读取(O后面没有F,默认有A)
FFILENAME O E DISK
(3) 读取数据并更改和/或删除,不追加记录
FFILENAME UF E K DISK
(4) 对文件进行修改,以及增加记录的操作:
FFILENAME UF A E K DISK
(5) 对文件进行查询,增加记录的操作,并对文件进行查询操作:
FFILENAME IF A E K DISK
追加:WRITE 更新:UPDATE 删除:DELETE
(6) 声明两个记录格式相同的文件,并对其中之一进行重命名 :
FPFFHSL1 IF E K DISK
FPFFHSL2 IF E K DISK RENAME(FMTFHS:FMTFHS2)
(7) 对文件的修改操作进行日志处理:
FPFFHSL2 UF E K DISK COMMIT
COMMIT:该文件记录的数据操作进行日志处理
RENAME:对文件记录格式名进行重命名。(适用于两个LF的文件格式名相同),RENAME需要使得新记录格式名唯一,它并不会真正的更改文件的记录格式名,仅是在当前运行程序中进行重命名。对同时运行的其它程序无影响。
FPFFHSL1 IF E DISK
FPFFHSL2 IF E DISK RENAME(FMTFHS:FMTFHS2)
4. RPG之D行具体操作:
变量数据类型:DS(数据结构) C(常量) A(字符型) S(字符型)
D MYDS E DS EXTNAME(PFFHS) //定义外部变量的格式,E为外部变量标志,DS数据结构
和
D MYDS DS
D FHS01 1 2
D FHS02 3 4
D FHS03 5 6
是等价的
D MYDS DS (定义结构体,不需要填写数据类型,默认为字符型,如果不初始化而直接使用会出错)
D DSFLD01 1 2 //1 在“From”项, 2 在“To/length”项
D DSFLD02 3 4
和
D MYDS DS
D DSFLD01 2 //2 在“To/length”项
D DSFLD02 2
是等价的
定义常量,在程序段中,不能对常量进行赋值操作。
D MYNUM C CONST('abcdefghijklmn')
此项为空,表示定义的变量为 3 位长的字符型。
D MYFLD01 S 3 //定义为3 位字符型
此项不为空(右对齐),表示定义的变量为数字型
D MYFLD01 S 3 2 //定义数字型变量,1 位整数,2 位小数(总长为3 位)
也可以这样写:
D wmsge S 10A
D wtime S 14S 0
定义一个10 位长,其中含2 位小数的字符型变量,并使其初始值为1
D MYFLD S 10 2 INZ(1)
定义一个每条记录为5 位长字符型变量,共10 条记录的数组
D MYFLD S 5 DIM(10) DESCEND //降序
定义一个10 位长的字符型变量,再定义一个变量,参照前一变量定义
D MYFLD01 S 10
D MYFLD02 S LIKE(MYFLD01)
定义一个结构,由一个3 位长的字符变量,和一个10 位长,其中2 位小数的数字变量组成
D MYDS DS
D MYDS01 3
D MYDS02 10 2
定义一个结构变量,结构内容参照外部文件PFFHS
D MYDS E DS EXTNAME(PFFHS)
定义一个结构变量,结构内容参照外部文件PFFHS,并且将第二个字段重命名为FHS999
D MYDS E DS EXTNAME(PFFHS)
D FHS999 E DS EXTFLD(FHS02)
定义一个日期型变量,格式为yyyy-mm-dd
D MYDATE S D DATFMT(*ISO)
5. PGB之 C行具体操作:
程序结束的标志:
C SETON LR(Last Record)
C RETURN
或者
C EVAL *INLR='1'
C RETURN
含义为:强制将内存中的数据写到磁盘中。基于效率因素,系统在修改文件时,会先将修改的结果先放到内存中,在同一程序中,读取数据也是先从内存中查询。
D FLD01 S 2 INZ(‘01’)
与
C MOVE ‘01’ FLD01 2 //2 在length 处,右对齐
是等价的
与 length 相呼应,当此项有值时,表示定义的是一个数字型变量,该项表示小数位长度。
如
C Z-ADD 2 FLD02 3 2
即是说,将 FLD02 定义为一个3 位长,其中1 位整数,2 位小数的数字变量,并赋值为2.00
(1) ADD
1. 基本语法:
Factory 1 Operation Factory 2 Result
FHS01 ADD FHS02 FHS03 // RPG 的语法
等价于
EVAL FHS03=FHS01+FHS02 //RPGLE 的语法
FHS01、FHS02、FHS03 必须都为数字型变量(P 型,或S 型),或者就是数字
意思是将 Factory 1 项的数据,加上Factory 2 项的数据,赋值到Result 项上
2. 语法二:
如果这样写的话:
Factory 1 Operation Factory 2 Result
ADD FHS02 FHS03
就等价于:
EVAL FHS03=FHS03+FHS02
3. 四舍五入:
(H)表示四舍五入,如FHS02=12.50(4,2),FHS03=3(2,0),那么
ADD(H) FHS02 FHS03
执行之后,FHS03=16(因为进位了)
而
ADD FHS02 FHS03
执行之后,FHS03=15
不过实际使用中,我们都尽可能使相加的字段小数位数相等,所以ADD 操作码一般都没有使用到四舍五入的功能。
(2) CALL:调用外部程序
1、如果是直接调用外部程序,那么程序名称需要用单引号括起来,且该程序必须存在。如
CALL ‘FHSILE01’ 就表示调用“FHSILE01”这个外部程序
2. 如果没有用单引号,如CALL FHSILE01就表示,FHSILE01 这时是个字符型变量(即并非调用“FHSILE01 这个程序),调用的是变量内容所代表的程序。如:
FHSILE01=’FHS01’时,表示调用“FHS01”这个外部程序;
FHSILE01=’FHS02’时,表示调用“FHS02”这外外部程序
也就是说,CALL 操作码调用的程序名,可以是一个变量名。
3.被调用的外部程序如果有接口参数,那么 CALL 操作码之后,也需要有“PARM”操作码相对应
(3) CAT:字符连接
1. 基本语法:
Factory 1 Operation Factory 2 Result
FLD01 CAT FLD02:0 FLD03
这句话的意思,是将FLD02 拼在FLD01 后面,中间没有空格,然后将拼出的结果赋值到FLD03 中。
FLD02:0,表示FLD02 与FLD01 之间的空格数为0,依此类推
FLD02:1,就表示FLD01 后面加一个空格,再拼上FLD02
Factory 1 项,与Factory 2 项可以是字符型变量,也可以就是字符。当是字符时,需要用单引号将字符括起来
2. 字段 FLD01 如果内容后面有空格,如“ABC ”,那么在CAT 操作时,系统会自动将后面的空格截去,只取’ABC’。
(4) CLEAR:清除内容:将目标所对应的所有变量/字段都赋上空值。
(5) CLOSE:关闭文件
允许使用*ALL 变量,来表达关闭所有已打开的文件:CLOSE *ALL
(6) COMMIT:日志事物处理的确认操作
(7) DEFINE
根据已知的字段,来定义新字段,如下:
*LIKE DEFINE FLD01 FLD02
这句话的意思,就是说“象定义字段 FLD01 一样,定义字段FLD02 的类型、长度”
(8) DELETE
(9) DIV:除
FLD01 DIV FLD02 N
MVR M
上面两句话的意思,是说,用FLD01 来除FLD02,将商赋值到变量N 中,将余数,赋值到变量M 中。(N,M 都是数字型变量)
(10) DO
1 DO 10 N
处理过程
ENDDO
含义为:循环10次,N表示循环到第几次
(11) DOU
DOU FLD01>FLD02
处理过程
ENDDO
上面这句话,就是说当FLD01 小于或等于FLD02 时,进行循环;当满足条件,即FLD01大于FLD02 时,结束循环。
(12) DOW
DOW FLD01>FLD02
处理过程
ENDDO
上面这句话,就是说当 FLD01 小于或等于FLD02 时,不进行循环循环;当满足条件,即FLD01 大于FLD02 时,才进行循环。
一般主要使用DO和DOW,在使用DOW时,常使条件永远成立,即死循环,然后在循环体中用IF语句判断何时退出循环(使用LEAVE语句)。
(13) DSPLY:屏幕显示
FLD01 DSPLY
就是在屏幕上,显示 FLD01 的内容
(14) ELSE ELSEIF
(15) IF--ENDIF BEGSR--ENDSR DO--ENDDO FOR--ENDFOR
(16) EVAL
EVAL FLD01=FLD02
等价于:
EVAL FLD01=*BLANKS
MOVEL FLD02 FLD01
(17) EXSR:执行子过程
(18) FOR
FOR N=1 TO 10
处理语句
ENDFOR
(19) ITER--continue
(20) LEAVE--退出当前循环--break
(21) MOVE:赋值语句
(22) MOVEL:左对齐赋值语句
(23) MULT:乘
FLD01 MULT FLD02 FLD03
等于
EVAL FLD03 = FLD01 * FLD02
(24) MVR:取余
(25) OPEN:打开文件
(26) OTHER与SELECT
SELECT
WHEN 条件判断1
处理语句 1
WHEN 条件判断2
处理语句 2
OTHER
处理语句3
ENDSL
(27) PARM :定义入口参数
*ENTRY PLIST
PARM FLD01
(28) READ:读取记录
READ 文件记录格式名
READP:游标指向上一条记录
(29) SETGT:定位操作—大于
2 SETGT 文件记录格式名
READ 文件记录格式名
这个 READ 操作,READ 到的,是第3 条记录。也就是说,SETGT 操作码,会将游标定位到大于键值的第一条记录前。
(30) SETLL:定位操作—小于
(31) SUB:减法
(32) SUBST:取字符/字符串
2 SUBST FLD01:3 FLD02
表示从字段 FLD01 的第3 位开始,取2 位,左对齐赋值到字段FLD02 中。
与
EVAL FLD02=%SUBST(FLD01:3:2)
等价
EVAL %SUBST(FLD02:3:2)=’01’
使字段FLD02 的第3、4 位(即从第三位开始,两位长)等于“01”
(33) UPDATE:修改记录
在执行UPDATE 的时候,必须先使用READ、CHAIN 等操作码锁定一条记录。如果未锁住记录,UPDATE(保存) 操作码将会报错。当执行了UNLOCK、UPDATE、以及ROLBK 语句时,等于是解锁,此时再执行UPDATE 操作码之前,必须再次锁住记录操作;
(34) WRITE:写记录
(35) XLATE:将一个字符串中指定的字符,更换成另外的字符。
'A':'9' XLATE MYCHAR1 MYCHAR2
将字符串MYCHAR1 中所有的“A”都变成了“9”
'A':'9' XLATE MYCHAR1:4 MYCHAR2
MYCHAR2 等于“ABC999C123”,指从第4 位开始(含第4 位),将“A”变成“9”赋值。
(36) Z-ADD:向数字型变量赋值
Z-ADD FLD01 FLD02
将数字型变量 FLD01,赋值到数字型变量FLD02 中。
(37) *ALL
EVAL FLD01=*ALL’0’
表示将字符型变量 FLD01 赋值为全’0’
CLOSE *ALL
就表示关闭所有文件
(38) %LEN:取字符串的长度
,%TRIM 是去字符串左边的空字符;%TRIMR 是去字符串右边的空格。
EVAL MYLEN = %LEN(%TRIMR(FLD01))
这时的 MYLEN,就是指变量FLD01 中的有效长度
(39) *LOVAL SETLL 记录格式名:表示将游标定位在所有记录之前
常用的循环读取文件的写法
*LOVAL SETLL 记录格式名
DOW 1=1
READ 记录格式名
IF *IN58=’1’
LEVAE
ENDIF
ENDDO
*HIVAL 与之相反,意思就是指对于键值而言的一个最大值,也就是将游标定位到所有记录之后,常与READP 一起使用,即先将游标定位到文件最末尾,然后倒序,向上读取。
6. 加锁和解锁
加锁:CHAIN READ
解锁:UPDATE DELETE COMMIT ROLBK CLOSE
7. DEBUG
(1) 程序编译:如果想对程序进行DEBUG,必须在编译时指定参数
编译程序时,先按F4,再按F10,修改编译参数的值
RPGLE 程序: Debugging views (DBGVIEW) 选项填“*LIST”,或“SOURCE”
(2) 执行 DEBUG 命令
在命令行,输入 STRDBG + 程序名 然后按F4,这两个参数要选为“*YES” :
Update production files (UPDPROD)
OPM source level debug (OPMSRC)
设置断点:在目标代码行按F6键,设置成功将会反白显示,取消断点的话在该行再按下F6键。
(3) 运行程序
设置好断点以后,按F12(退出当前环境)或shift+F9(在DEBUG状态下调出命令行)
然后执行 CALL 程序名
这时将会执行到首个断点处,并显示处DEBUG模式
(4) 在DEBUG模式中进行调试
F3:退出系统(不执行下面的语句)
F6: 定位断点
F10 :步向下执行程序
F11: 查看当前光标处的变量的值
F12 :程序运行到下一断点处(若无断点,则程序会运行完毕)
F21: 调出交互式命令行
在 DEBUG 模式的命令行中执行:(注意,是DEBUG 模式的命令行,不是用F21 调出的交互式命令行)
EVAL 变量名,查看当前变量的值;(如EVAL FLD01,就是查看字段FLD01 的值)
F 字符串顺序向下查找字符串(如 F FHS,光标将会跳至顺序向下,代码段中首个FHS 字符串处
F16 继续查找下一个字符串(紧接在F 字符串后使用)
当结束调试时,必须输入“ENDDBG”用来结束DEBUG 调试模式。
8. 编译
在编译程序时如果出错,在命令行执行“WRKSPLF”,然后用SHIFT+F6 去到最末尾,可以看到名称为“程序名”的脱机文件(SPOOL FILE),用5 进入,查看出错信息。在Control处填"B",确认,到最末尾。
00和10可以忽略,20和30必须解决
常见编译出错信息:
RNF2120:声明的文件不存在
RNF7030:变量未定义
运行时的出错信息:
CPF4328:对声明的文件使用了COMMIT 关键字,但该文件未加入到日志文件中
CPF4131:文件重新编译过,但之后未重新编译该程序
CPF128:PF 文件damage(被破坏)
Decimal Error:通常是给数值型变量赋值时,超长溢出
Attempt to write a duplicate record to file:试图向文件中写入重复键值
9. CL程序
程序的开始与结束:CL程序中的所有变量,都使用&做为前缀
PGM PARM(&A &B) /* 开始CL 程序 */
ENDPGM /* 结束CL 程序 */
在 CL 程序中使用到的变量,都必须使用DCL 语句来定义:
DCL VAR(&FLD01) TYPE(*CHAR) LEN(10)
DCL VAR(&FLD02) TYPE(*DEC) LEN(10 2)
上述语句表示:
定义变量 FLD01,10 位长的字符型变量
定义变量 FLD02,10 长,其中2 位小数的数字型变量
10. 调试
A3MONLOG Z1DEMO11(作业条的名字,去除RP)
在程序前面的opt中输入SD
在指定的行数前面输入F6设置断点
设置好断点之后,按F12键(退出当前环境)或SHIFT+F9出现交互式模式
执行CALL + 程序名,这时程序会执行到首个断点处,并显示DEBUG模式
在DEBUG模式中,可做如下操作:
F3 退出程序(不执行下面的语句)
F6 定位断点,再按一下是取消断点
F10 单步向下执行程序
F11 查看当前光标处的变量的值
F12 程序运行到下一个断点处