RPG 入门

本文档是一份AS/400程序员培训手册,详细介绍了RPGLE编程的基础,包括程序流程、D/F/C行的用法、入口参数、数据库交互、调试技巧和实用命令。内容涵盖简单的程序编写、程序流程控制、D行和F行的声明与使用、C行的ILE操作码、数据库相关知识如LF和MEMBER、游标、事务处理、DEBUG调试方法,以及CL和CMD命令的使用。此外,还讨论了屏幕文件、数组的使用、SQLRPGLE和SAVF的备份恢复等高级主题,旨在帮助读者全面掌握AS/400平台上的RPGLE编程。
摘要由CSDN通过智能技术生成

AS/400 程序员培训手册
(中级)
作者: 万一飞(Chinaunix 网友:胖有型)
目 录
1 简单说明 ................................................................................................................................... 5
2 程序代码行的编写 ................................................................................................................... 5
2.1 最简单的RPGLE 程序 ............................................................................................ 5
2.2 举例准备 ................................................................................................................... 5
2.3 简单的程序流程 ....................................................................................................... 6
2.4 常见的程序流程 ....................................................................................................... 7
2.5 F 行说明 ................................................................................................................... 8
2.5.1 内容说明 ........................................................................................................... 8
2.5.2 常用例子 ......................................................................................................... 11
2.5.3 补充说明 ......................................................................................................... 12
2.6 D 行说明 ................................................................................................................. 12
2.6.1 内容说明 ......................................................................................................... 12
2.6.2 常用例子 ......................................................................................................... 15
2.6.3 补充说明 ......................................................................................................... 16
2.7 入口参数 ................................................................................................................. 16
2.8 C 行说明 ................................................................................................................. 18
2.8.1 写在前面 ......................................................................................................... 18
2.8.2 内容说明 ......................................................................................................... 19
2.8.3 ILE 操作码分类: .......................................................................................... 20
2.8.4 ILE 操作码 ..................................................................................................... 21
2.8.4.1 A--C ......................................................................................................... 21
2.8.4.2 D--E .......................................................................................................... 29
2.8.4.3 F--N .......................................................................................................... 34
2.8.4.4 O--R ......................................................................................................... 41
2.8.4.5 S--Z .......................................................................................................... 45
3 和程序相关的数据库知识 ..................................................................................................... 51
3.1 LF(逻辑文件) .................................................................................................... 51
3.1.1 逻辑文件概念 ................................................................................................. 51
3.1.2 逻辑文件对效率的影响 ................................................................................. 53
3.2 MEMBER ............................................................................................................... 53
3.3 游标 ......................................................................................................................... 54
3.3.1 游标的概念 ..................................................................................................... 54
3.3.2 不同操作码对应的游标的处理 ..................................................................... 54
3.3.3 “有且仅有”的游标 ..................................................................................... 55
3.3.4 LOVAL、HIVAL 对应的游标操作 ............................................................... 55
3.4 事务处理 -- COMMIT ........................................................................................... 56
3.4.1 概念描述 ......................................................................................................... 56
3.4.2 使用方法 ......................................................................................................... 56
3.4.3 注意事项 ......................................................................................................... 57
3.5 关于锁表的问题 LCKW ....................................................................................... 58
4 DEBUG 调试以及常见出错信息 .......................................................................................... 58
4.1 写在前面 ................................................................................................................. 58
4.2 常规用法 ................................................................................................................. 59
4.2.1 程序编译 ......................................................................................................... 59
4.2.2 执行DEBUG 命令 ......................................................................................... 59
4.2.3 运行程序 ......................................................................................................... 59
4.2.4 在DEBUG 模式中进行调试 ......................................................................... 60
4.2.5 跟踪被当前程序调用的程序 ......................................................................... 60
4.2.6 一定要退出DEBUG 模式 ............................................................................. 61
4.2.7 补充 ................................................................................................................. 61
4.3 跟踪批处理程序( From qingzhou) ......................................................................... 62
4.4 常见的出错信息 ..................................................................................................... 62
4.4.1 编译程序时的出错信息 ................................................................................. 62
4.4.2 运行时的出错信息 ......................................................................................... 64
5 CL、CMD .............................................................................................................................. 64
5.1 CL 程序 ................................................................................................................... 64
5.1.1 基本认识 ......................................................................................................... 64
5.1.2 CL 程序的常用语法及命令: ....................................................................... 65
5.1.3 不常用的语法 ................................................................................................. 67
5.2 CMD ....................................................................................................................... 68
6 屏幕文件及使用 ..................................................................................................................... 69
7 实用技巧 ................................................................................................................................. 74
7.1 数组 ......................................................................................................................... 74
7.1.1 简述 ................................................................................................................. 74
7.1.2 定义 ................................................................................................................. 74
7.1.3 初始化 ............................................................................................................. 75
7.1.4 使用方法 ......................................................................................................... 75
7.1.5 补充 ................................................................................................................. 76
7.2 结构体 ..................................................................................................................... 76
7.2.1 简述 ................................................................................................................. 76
7.2.2 结构体的定义 ................................................................................................. 77
7.2.3 初始化 ............................................................................................................. 77
7.2.4 使用方法 ......................................................................................................... 78
7.2.5 结构体中的数组 ............................................................................................. 79
7.2.6 定义时,独立变量与结构体变量的区别 ..................................................... 79
7.2.7 不带OCCURS 关键字的结构体定义 ........................................................... 80
7.3 按内部序号来读文件 ............................................................................................. 80
7.3.1 简述 ................................................................................................................. 80
7.3.2 定义 ................................................................................................................. 81
7.3.3 使用方法 ......................................................................................................... 81
7.4 常驻内存命令SETOBJACC ................................................................................. 83
7.4.1 简述 ................................................................................................................. 83
7.4.2 命令说明 ......................................................................................................... 83
7.4.3 使用说明 ......................................................................................................... 84
7.4.4 补充说明 ......................................................................................................... 84
7.5 数据队列的使用 ..................................................................................................... 84
7.5.1 数据队列的说明 ............................................................................................. 84
7.5.2 CRTDTAQ 建立数据队列 ............................................................................. 85
7.5.3 DLTDTAQ 删除数据队列 ............................................................................. 85
7.5.4 系统API ......................................................................................................... 86
7.5.4.1 QSNDDTAQ 发送数据队列 ................................................................ 86
7.5.4.2 QRCVDTAQ 接收数据队列 ................................................................ 86
7.5.4.3 QCLRDTAQ 清除数据队列 ................................................................ 87
7.5.4.4 QMHQRDQD 检索数据队列 ................................................................ 87
7.6 使用系统API 的入手方法 .................................................................................... 87
7.6.1 调用说明 ......................................................................................................... 87
7.6.2 关于USR SPACE ........................................................................................... 88
7.6.3 一些可能常用的API ..................................................................................... 88
8 其它......................................................................................................................................... 89
8.1 报表打印 ................................................................................................................. 89
8.2 SQLRPGLE ............................................................................................................ 93
8.3 SAVF,备份与恢复 ............................................................................................... 95
8.4 菜单--MENU .......................................................................................................... 96
8.5 实用命令 ................................................................................................................. 96
8.6 关于代码风格的几点想法 ..................................................................................... 99
1 简单说明
RPG 的全称:Report Program Generator
内部交流、亦可作培训使用。对用户作如下假定:
1、能 COPY、修改、编译源代码(RPGLE、CLP),并能运行编译后的程序
2、能 COPY、修改、编译文件(PF、LF、PRTF、DSPF);
3、对数据文件(PF)有简单的认识(FIELD 􀃆 RECORD 􀃆 PF),并知道LF 与PF 的
对应关系。
2 程序代码行的编写
2.1 最简单的RPGLE 程序
为便于理解,这里写一个最简单的 RPGLE 程序
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
*************** Beginning of data *************************************
0001.00 C 'HELLO WORLD' DSPLY
0002.00 C RETURN
****************** End of data ****************************************
这个程序编译成功,并调用(CALL 程序名),就是在屏幕上反白显示“HELLO
WORLD”字样。(其中,绿色字样,是系统自动显示的,下同)
与自由风格的 C 语言不同,RPGLE 中的编码,是有一定的格式,如果写错,将会在当
前代码行上高亮反绿显示。初学者如果不太清楚从何处开始下手,可以使用“F4”键查看
(F4 键只有用2 进入的编辑状态才有效,用5 进入的查看状态是无效的)
Level N01 Factor 1 Operation Factor 2 Result
'HELLO WORLD' DSPLY
Decimal
Length Positions HI LO EQ Comment
关于每一项所对应的内容代表什么意思,该如何填写,即如何写程序,将会在下面的具
体讲解。
2.2 举例准备
列出表名,字段,以方便下面的举例。
假设有PF 文件叫PFFHS,文件的记录格式叫FMTFHS
每条记录,都是由FHS01、FHS02、FHS03 三个字段组成,每个字段都是两位长的字符
型变量。
逻辑文件 PFFHSL1 的键值为FHS01
逻辑文件PFFHSL2 的键值为FHS02
逻辑文件PFFHSL3 的键值为FHS01、FHS02
注:
文件的记录格式,可以理解为给这个文件整条记录起的一个名字;或者是说将每条记录
视都视做一个类型相同大变量,然后给这个大变量起的名字。所以文件的记录格式信息中,
包含有一条记录由多少个字段组成,总计长度是多少这样的信息。
文件的记录格式,与各个字段同时定义。(写文件的源码时)
文件的记录格式在 RPGLE 的程序中,不能与文件名相同。
2.3 简单的程序流程
为方便起见,系统自动显示的就不再贴出来了,只贴代码段。
FPFFHS UF E DISK
C READ FMTFHS
C EVAL FHS01=”01”
C UPDATE FMTFHS
C SETON LR
C RETURN
这个程序的意思,是说读PFFHS 这个文件,然后将读到的第一条记录中的FHS01 这个
字段的值修改为“01”。
“SETON LR”,LR 的位置可在HI、LO、EQ 中任选一处。意思是指将打开指
示器*INLR,即赋值使指示器*INLR 的值等于1。等价于“ EVAL *INLR=’1’ ”,
意思是强制将内存中的数据写到磁盘中。(基于效率因素,系统在修改文件时,会先将修改
的结果先放在内存中,在同一程序中,读取数据也是先从内存中查询。)LR,取自是Last
Record
RETURN,表示程序结束,在后面“操作码”一节中,会有讲述。
如果不太明白,就记住
C SETON LR
C RETURN

C EVAL *INLR=’1’
C RETURN
这两句话加在一起,表示程序结束就可以了。
从这个程序中,我们可以看到,RPGLE 的程序,大致上可以分为两个部分:
1、声明、定义部分:声明程序中使用到的文件(F 行),定义程序中使用的变量(D 行)
2、程序运行部分 :即 C 行,也就是程序段。
在RPGLE 程序中,F 行必须在D 行前面,D 行必须在C 行前面。
程序执行的起始顺序,将从定义部分之后,第一个 C 行开始,顺序向下执行。
程序中的 F 行、D 行都不是必须项,一个程序可以没有F 行(如仅完成计算功能的公
共函数,比如计算利息),也可以没有D 行(没有需要特别定义的变量,或者所有变量都在
C 行进行定义),但不应该没有C 行,因为F 行与D 行都属于非执行行,是起定义作用;C
行是执行行。没有C 行的程序,是无执行意义的。
2.4 常见的程序流程
FPFFHS UF E DISK //声明文件PFFHS
D LSFLD01 S 2 //定义临时变量LSFLD01
C EVAL LSFLD01=’01’ //给变量LSFLD01 赋值
C EXSR SUB#UPD //执行子过程SUB#UPD
C EVAL LSFLD02=’02’ //给变量LSFLD02 赋值
C EXSR SUB#UPD //执行子过程SUB#UPD
C SETON LR //数据写入磁盘
C RETURN //程序结束
C SUB#UPD BEGSR //子过程SUB#UPD 开始
C READ FMTFHS //读PFFHS 文件
C EVAL FLD01=LSFLD01 //给字段FLD01 赋值
C UPDATE FMTFHS //修改文件
C ENDSR //子过程结束
“//”后面的,只是简单的解释,如果自已动手写,不需要输入这些内容。
系统在运行这个程序时,是按如下的顺序来执行:
1. 首句 EVAL 赋值语句,直接执行;
2. 当系统发现操作码“EXSR”时,根据后面的变量名“SUB#UPD”,去查找对应的
“SUB#UPD BEGSR”语句;
3. 然后从“SUB#UPD BEGSR”之后,顺序向下执行,直至“ENDSR”语句
4. 执行到“ENDSR”之后,将会再回到当初的“EXSR SUB#UPD”处,继续向下
执行,直到RETURN 语句为止
这里提出一点要注意,如果子过程中,又执行了自身,即在SUB#UPD 程序中,又出现
了“EXSR SUB#UPD”,是可以编译通过的,但在执行过程中,系统会因为无法定位,
而出现死循环,直至报错异常中断退出。也就是RPGLE 的程序中,子过程不允许出现递归。
2.5 F 行说明
2.5.1 内容说明
首位填上 F,然后按F4,会出现如下内容:
File File End of File
Filename Type Designation File Addition Sequence
File Record Limits Length of Record
Format Length Processing Key Field Address Type
File
Organization Device Keywords
Comment
各项的含义分别是:
Filename:
需要声明的文件名,必须顶格,文件名必须唯一,也就是程序中对同样的文件名不能声
明两次。
File Type:
声明文件的处理类型。必须填写。允许的选项有:
I: 输入型,即只读文件,对声明的文件只取其记录的值,不对记录进行修改
U: 修改型,即对声明的文件进行修改操作(删除记录属于修改操作的一种)
O: 输出型,即只写,对声明的文件只进行写操作。
C:混合型,用于对屏幕文件的定义。(混合型,即输入/输出型,以屏幕文件为例,也
就是读取屏幕文件的一些输入字段信息,同时也可以输出一些字段的值到屏幕文件中,但不
能对屏幕文件自身进行修改,所以与上面的U 是有区别的)
File Designation:
文件的指定方式,允许的选项有:
不填:表示这是一个输出文件,即“File Type”项为“O”时,此项不填
P:表明声明的文件是主文件,这个很少用,cycle 相关
S:表明声明的文件是次文件,这个没用过,cycle 相关
R:Record address file,记录地址文件?没用过
T:数组或表文件?不懂,没用过
F:常用,具体含义不知道该如何翻译(Full procedural file)
简单来说,不考虑cycle(循环控制),这样理解就够了:
当“File Type”为I,U,C 时,这里填“F”
当“File Type ”为O 时,这里不填写
End of File:
程序结束前,对记录的处理方式。可以不填,或填“E”。但从英文解释上来看,不敢
妄下定论,似乎不填,表示在程序结束前,要处理所有文件的所有记录(含LF?);填E,
表示只处理这个文件的所有记录?
总之,此项一般是不填。
File Addtion:
是否会增加文件中的记录,即是否会对文件进行写操作。
可以不填,或填“A”
当 File Type 为“O”时,系统自动默认此项为“A”,不必填写;
当 File Type 为“I”,或“U”时,这项内容可以填“A”,也可以不填。不填,即表示不
会增加文件中的记录,也就是没有写操作;填“A”时,即表示会增加文件中的记录,也就
是会对文件进行写操作。
Sequence:
针对 cycle 使用的,表示排序顺序。(Cycle 我没有用过,估计可能是使用控制起来,程
序代码不那么直观,不利于上手和维护,所以现在已经不流行使用了。)
当定义为非 cycle 文件时,即“File Designation”项非“P”、“S”时,此项必须为空;
当定义为 cycle 文件时,即“File Designation”项为“P”、或“S”时,此项可填空、A、
D。A 表示升序,D 表示降序。
因为 CYCLE 现在已不常用,所以通常不填。
File Format
文件格式,不能为空,允许的值有:
E: 声明的文件,是外部描述的文件(即文件在程序运行之前就已存在?)
F: 声明的文件,是一个程序描述文件?(不知道什么意思,没用过)
这里通常填“E”,即为外部描述文件
Record Length
“File Format”为“F”时,才需要填写。没用过
通常不填
Limit Processing
不懂。
通常不填。
Length of Key Field
查询时,索引键值的长度
如果“File Format”项等于“E”,即外部描述文件时,此项不填
如果“File Format”项等于“F”,便不需要按KEY 值查询时,此项也不填
如果“File Format”项等于“F”,需要按KEY 值查询时,此项填写KEY 值的长度
(1—2000)。
因为一般都使用外部描述文件,所以这里一般都不填写。
Record Address Type
记录寻址类型,好象是对文件键值的描述。允许的值如下:
空:不使用KEY 值,在程序段中,不会对文件的查询定位操作,如“SETLL”、“CHAIN”
操作码都不会用的时,该项填空。
K: 使用 KEY 值,即表示会对声明的文件进行查询定位操作,此时声明的文件必须有
键值,即必须为逻辑文件(LF 文件),或在生成文件时,已加入了KEY 值。
(下面的选项应该是程序描述文件才会使用)
A: KEY 值为字符型
D:KEY 值为日期型
F:KEY 值为数字型
G:KEY 值为非英文字符
P:KEY 值为压缩型数字
T:KEY 值为时间型
Z:KEY 值为timestamp?
总之,如果要按照键值对声明的文件进行查询定位操作(即程序中使用了CHAIN、
SETLL 操作码,则此项需要填写“K”;如不需要进行查询操作,则不填。),此项填“K”
时,声明的文件必须含有KEY 值。
File Organization
不知道,一般不填
Device
声明文件的存放位置,必须填写,允许的值有:
DISK: 磁盘文件,即文件存储在磁盘上,最常见的;
PRINTER: 打印文件,提供打印输出描述,以及对打印设备访问。打印报表用这个;
WORKSTN: workstation,工作站,显示文件。屏幕文件(DSPF)的定义用这个值
(下面这两种我没用过的)
SEQ: 磁带文件,文件存储在磁带上。
SPECIAL: 特殊文件,我现在也不是很清楚具体使用方式。据blogliou 说,这种类型,
是允许指定一种不能被RPG 直接操作的输入/输出设备。比如可以通过SPECIAL 文件,在
RPGLE 程序中实现象读写磁盘一样,对DTAQ 进行程序间数据交换。
Keyword
可以不填,常用的值有(这里只列出几个常用的):
COMMIT
该文件记录的数据操作进行日志处理(关于日志处理,后面会章节会讲到)
RENAME
对文件记录格式名进行重命名。比如说程序中需要同时声明 PFFHSL1,PFFHSL2
这两个逻辑文件。这两个逻辑文件的记录格式名都是一样(通常和PF 一样,即都为
FMTFHS;不过也可以定义成不同。如果不同,当然就不需要使用RENAME 键字了)。
那么,为了能让系统区分,就必须对其中一个的记录格式名进行重命名。RENAME
的语法:RENAME(旧记录格式名:新记录格名),如下:
FPFFHSL1 IF E DISK
FPFFHSL2 IF E DISK RENAME(FMTFHS:FMTFHS2
新记录格式可以自由定义,只要在该程序中无同名的即可。RENAME 并不会真正
的更改文件的记录格式名,仅是在当前运行程序中进行重命名。对同时运行的其它程序
无影响
USROPN
对于声明的文件,由用户自行打开。如果不填写此关键字,系统将会在程序最最开
始(执行第一句C 行语句前),自动执行“OPEN 文件” 的操作,在程序结束后,自
动执行“CLOSE 文件”的操作。而填写此关键字之后,OPEN,CLOSE 的操作将由用
户在C 行程序段中,自行处理。如果用户未执行OPEN 操作,就执行CHAIN、READ、
SETLL 等语句,在编译程序时就会报错。程序在结束之前,必须关闭所有已打开的文
件,所以用起来会比较繁琐。USROPN 常作用于对文件的解锁,在同一程序中打开同
一文件的不同MEMBER 等,属于一个较高级的用法,可在实际操作中慢慢体会。
OPEN,CLOSE 的操作码,对应的是文件名,不是记录格式名。即
C OPEN PFFHSL1
C CLOSE PFFHSL1
而不是
C OPEN FMTFHS
Comment
注释说明。源自RPG,在RPG 中是有作用的,可以对程序作简短的说明,但在RPGLE
中,其实已经没有作用了,此项不用填。(填了也没用)
2.5.2 常用例子
对文件进行只读的声明:
FPFFHS IF E DISK
对文件进行修改的声明:
FPFFHS UF E DISK
对文件进行只写的声明:
FPFFHS O E DISK
对文件进行修改,以及增加记录的操作:
FPFFHS UF A E DISK
对文件进行查询,增加记录的操作,并对文件进行查询操作:
FPFFHSL1 IF A E K DISK
声明两个记录格式相同的文件,并对其中之一进行重命名
FPFFHSL1 IF E K DISK
FPFFHSL2 IF E K DISK RENAME(FMTFHS:FMTFHS2)
注:在声明时,两个文件不一定要上下紧接着;随便改哪一个文件对应的记录格式
都可以;新旧记录格式名用冒号隔开,新记录格式名可自行定义,无规则。
对文件的修改操作进行日志处理:
FPFFHSL2 UF E K DISK COMMIT
cycle 类文件的声明:
FPFFHSL2 IP E K DISK
这样文件声明为P 之后,程序中不需要写循环读文件,也不需要写RETURN,设指示器INLR,
也就是
FPFFHSL2 IP E K DISK
C READ 记录格式名
等价于
FPFFHSL2 IF E K DISK
C DOW 1 = 1
C READ 记录格式名 EQ 指示器
C IF EQ指示器=’1’
C LEAVE
C ENDIF
C ENDDO
C RETURN
2.5.3 补充说明
声明的文件,可以同时使用多个keyword 关键字,并可以不在同一行(但必须紧接在声
明的文件的下面),如下:
FPFFHSL2 IF E DISK RENAME(FMTFHS:FMTFHS2)
F COMMIT
即表示文件PFFHSL2,同时使用了RENAME、COMMIT 两个关键字。
如果写得下,也可以写在同一行,以空格键分开,如下
FPFFHSL2 IF E DISK COMMIT RENAME(FMTFHS:FMTFHS2)
2.6 D 行说明
首行填“D”,然后按F4,会出现如下内容:
Declaration To /
Name E S/U Type From Length
Internal Decimal
Data Type Positions Keywords
Comment
2.6.1 内容说明
Name:
定义的变量的名字,该名字可以不顶格写。(即允许有缩进)
E:
标识定义的变量是否源自外部数据结构。可以不填,或填“E”
上面的解释可能有点饶口,其实这个地方的意思,就是说:
如果是程序内部自行定义一个临时变量,此处不填;
如果是引用的一个外部文件作为数据结构,那么这里就要填“E” ;同时“Declaration
Type”处,就要填“DS”,即定义为一个结构;“Keywords”处要使用EXTNAME 关键字
所谓“引用一个外部文件作为数据结构”,也就是说定义一个结构,整个结构中的变量,
参照外部文件来定义。
所谓结构,可以理解为一个“由多个变量组合而成的大变量”。
举例而言:
D MYDS E DS EXTNAME(PFFHS)

D MYDS DS
D FHS01 1 2(1 在From 项;2 在To / length 项)
D FHS02 3 4
D FHS03 5 6
是等价的,都是定义一个结构变量MYDS(名字可以自行定义),这个结构变量是由三
个字符型变量FHS01,FHS02,FHS03 拼成的。
第一种定义方法,就是引用外部文件“PFFHS”作为数据结构的定义,注意使用到了
“EXTNAME”关键字,而且“E”项的值为“E”。
而第二种定义方法,就是直接定义一个结构“MYDS”。注意没有使用外部文件时,“E”
项的值为空。
S/U:
不知道,一般都填空。
Declaration Type:
定义变量的类型,允许的值如下:
不填: 非以下内容:数据结构、常量、独立变量、数组、表。此项为空时,好象只能
用来表示当前定义的变量是属于结构的一个变量。在下面会举例
DS: 数据结构,即定义一个结构变量,这个之前已讲过
C: 常量
常量只能使用字符,不需要定义常量的长度、类型。常量的内容写在
“Keywords”处,并使用CONST 关键字,在程序段中,不能对常量进行赋值操作。
D MYNUM C CONST('abcdefghijklmn')
就是定义一个叫做MYNUM 的常量,这个常量包含字母a--n。
PI: 不知道,没有用过
PR: 不知道,没用过
S: 定义以下内容:独立变量、数组、表
定义一个叫 MYFIELD1 的变量,变量为1 位长的字符型
D MYFIELD1 S 1 //1在“To/length”项
定义一个叫 MYARRAY 的数组,共含3 条记录,每条记录为1 位字符型
D MYARRAY S 1 DIM(3) //DIM在“Keywords”项
表的定义没有用过
总之,这一项,最常用的,就是“DS”、“S”与空。即结构体与独立变量,其它选项较
少用到。
From:
当“Declaration Type”项为“S”时,表示独立变量、数组,此项不填
当“Declaration Type”项为“DS”时,表示结构,此项仍然不填
当“Declaration Type”项为空时,表示当前定义的变量,属于上面定义的结构,此时,
此项可以填写,也可以不填写。
当填写时,“From”项表示变量在结构中的起始位置,右对齐;“To/length”表示变量在
结构中的结束位置,也是右对齐。
当不填写时,“To/length”表示直接定义为变量长度。
举例:
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
其实是等价的,都是定义一个结构变量MYDS,这个结构变量中,包含了两个变量
DSFLD01,DSFLD02,这两个变量都是两位长字符。所不同的是,第一种定义方法,是指
定了变量在结构中的位置;而第二种方法,是直接指定变量的长度和类型
注意到上面的定义中,DSFLD01、DSFLD02 的Declaration Type 为空,也就是表示这
两个字段是属于上面定义的结构MYDS。如果此项为“S”,即表示这个变量与结构无关
D MYDS DS
D DSFLD01 2 //2 在“To/length”项
D DSFLD02 S 2
在这个定义中,变量DSFLD02 就是一个独立的变量,与结构MYDS 无关。
Length:
上面已讲述在定义结构时的使用方法。
在定义非结构时,此项的内容即为定义变量的长度。右对齐
Internal Data Type:
定义变量的类型,允许的值有:
空:变量定义为字符型、压缩型数字
A: 变量定义为字符型
B: 二进制?不知道
D: 变量定义为日期型
F: 变量定义为浮点型?
G: 变量定义为图型?(非英文?汉字?)
I: 变量定义为带符号的整数
N: 变量定义为指示器变量?(没用过)
P: 变量定义为压缩型数字
S: 变量定义为普通的数型
T: 变量定义为时间型
U: 变量定义为无符号的整数
Z: 变量定义为日期+时间型(格式:年-月-日-时.分.秒.微秒)
*: 变量定义为指针型
其实我最常用,就是不填,因为一般的程序,有字符和数字这两种类型变量,就足够了。
Decimal Positions:
当变量定义为数字型时,用来标志小数的位数。
当“To/Length”项为3,“Internal Data Type”项为空时
此项为空,表示定义的变量为 3 位长的字符型
D MYFLD01 S 3 //定义为3 位字符型
此项不为空(右对齐),表示定义的变量为数字型
D MYFLD01 S 3 2 //定义数字型变量,1 位整数,2 位
小数(总长为3 位)
Keywords:
关键字,可以不填,常用的值如下:(同样,这里我也只列出几个常用的,这里先不做
详细说明,仅供参考,在后面的例子,看看就知道用法了)
CONST: 定义常量的值
DIM: 定义数组
EXTNAME:引用外部文件作为数据结构变量
EXTFLD: 对引用了外部文件作为数据结构的某个变量,进行重命名
LIKE: 定义变量时,参照已存在的变量定义
OCCURS: 定义结构体变量时,指定的结构体变量的记录条数
INZ: 定义变量时,赋值初始值
DATFMT: 定义日期变量时,指定日期格式
*MDY (mm/dd/yy)
*DMY (dd/mm/yy)
*YMD (yy/mm/dd)
*JUL (yy/ddd)
*ISO (yyyy-mm-dd)
*USA (mm/dd/yyyy)
*EUR (dd.mm.yyyy)
*JIS (yyyy-mm-dd)
Comment
注释项,源自RPG,不用填,因为填了也没用。
2.6.2 常用例子
定义一个 10 位长的字符型变量:
D MYFLD S 10
定义一个10 位长,其中含2 位小数的字符型变量,并使其初始值为1
D MYFLD S 10 2 INZ(1)
定义一个每条记录为5 位长字符型变量,共10 条记录的数组
D MYFLD S 5 DIM(10)
定义一个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)
2.6.3 补充说明
变量的定义,除了在 D 行定义之外,还可以在C 行通过赋值语句直接定义

D FLD01 S 2 INZ(‘01’)

C MOVE ‘01’ FLD01 2 //2 在length 处,右对齐
是等价的
定义结构之后,可以将结构变量视为一个普通的变量进行赋值来改变结构变量的值,也
可以通过对组成结构变量的变量进行赋值,来达到修改结构变量的值的目的。
如:
D MYDS DS
D MYFLD01 2
D MYFLD02 2
在 C 行中,这两句是等价的
C EVAL %SUBST(MYDS:3:2)=’01’
C EVAL MYFLD02=’01’
第一句是直接改结构变量 MYDS 的后两位的值(当然,此时MYFLD02 的值也变化了)
第二句是对 MYFLD02 进行赋值,同样,赋完值之后,MYDS 的后两位也变为’01’
在需要频繁进行数字与字符之间转换时,偷懒的人会通过定义这样的结构来达到目的:
D MYDS DS
D MYFLD01 1 8
D MYFLD02 1 8 0
比如说,给MYFLD01 赋值为’20070208’之后,MYFLD02 也就自动等于20070208;
然后给MYFLD02 加1 之后,MYFLD02 等于20070209,MYFLD01 的值也自动等
于’20070209’。可以认为结构变量MYDS 是字符型(即一直等于MYFLD01 的值)
这种方法,当需要字符型变量时,就使用MYFLD01;当需要数字变量时,就使用
MYFLD02,不过我总觉得有点类似于作弊,一般没用。
关于数组、结构体的内容,因为要说起来内容还颇多,而也属于略为高级一些的用法,
所以将在后面专设章节讲述。
2.7 入口参数
程序可以通过“*ENTRY”定义入口参数,或称之为接口参数,来传递数据。
假设有程序 FHS01ILE,其中入口参数的定义如下:
C *ENTRY PLIST
C PARM FLD01 3
C PARM FLD02 4
其中:
*ENTRY 在“Factor 1”项;
PLIST 在“Operation”项;
PARM 在“Operation”项;
FLD01、FLD02 都在“Result”项
上述定义,表示这个程序通过两个字段与其它外部程序沟通。那么别的程序(如
FHS02ILE)在调用程序FHS01ILE 时,就要带上两个字符型变量,如
C CALL ‘FHS01ILE’
C PARM FHSFLD01 3
C PARM FHSFLD02 4
在两个程序里,这两个变量名可以不同(比如说一边叫FHSFLD01,FHSFLD02;
一边叫FLD01,FLD02),但长度,类型必须匹配。
如果在 FHS02ILE 中,FHSFLD01 等于’123’,FHSFLD02 等于’abcd’,那么系统在
运行CALL 语句,执行程序FHS01ILE 时,将会对字段FLD01 初始化赋值,使其一开
始就等于’123’,字段FLD02 等于’abcd’。
如果 FHS01ILE 程序中,对FLD01、FLD02 进行了改动,比如FLD01 最后等于’789’,
FLD02 最后等于’efgh’,那么程序FHS02ILE 在调用完FHS01ILE 之后,FHSFLD01、
FHSFLD02 这两个字段也同样会改变,成为’789’,和’efgh’
也就是入口参数的变化是可以传递的,其实应该很好理解吧。
入口参数的定义,可以写在程序的任何一处,而程序的执行,始终是从 C 行的顺
序第一行开始执行,与入口参数所在的位置无关。
FHS02ILE 也可以使用一个大变量来调用FHS01ILE,只要总长相等即可(这种方
法仅限于被调用的程序FHS01ILE 的入口参数全部为字符型才可使用,仅仅只是不会
错,不建议这样使用。
C CALL ‘FHS01ILE’
PARM FHSFLD01 7
其实从上面的例子可以看出,入口参数可以使用结构的形式来表达,所以下面这种
写法也不会有错。(如果被调用程序有数字型变量,只要在定义结构时也定义为数字型
即可)
D MYDS DS
D DS01 3
D DS02 4
C CALl ‘FHS01ILE’
C PARM MYDS
不过要注意,如果RPG 程序调用C 程序,那么入口参数必须严格按照C 程序中的
来,比如C 程序中带了两个字符型参数,那么RPG 程序中也必须是两个字段入口参数,
不能使用由两个字符变量组成的结构。原理可以自行想想。
既然可以使用结构做为入口参数,当然,也可以参照外部文件来定义结构做为入口
参数
D MYDS E DS EXTNAME(PFFHS)
C CALL ‘FHS01ILE’
C PARM MYDS

C CALL ‘FHS01ILE’
C PARM FHS01 2
C PARM FHS02 2
C PARM FHS03 2
是等价的。
可以看到,参照外部文件定义结构做为入口参数时,可以有效的节省代码行,而且
不会出现遗漏。所以在实际使用中,常会看到,将一些公共程序的入口参数定义成一个
PF 文件。而调用它的程序,就参照这个PF 文件,定义结构做为调用的接口参数。
当接口参数不一致时,如 FHS02ILE 中漏了第二个参数时:
C CALL ‘FHS01ILE’
C PARM FHS01 3
此时,并不是一开始运行FHS01ILE 程序,系统判断入口参数不符就报错;实际上,
此时,FLD01 的值还是正确的,但FLD02 的值就处于一个未初始化的状态。于是,当
代码执行到与FLD02 有关的操作码时,才会报错;如果FHS01ILE 在运行的过程中,
因为逻辑判断(如IF 条件判断)的关系,而未执行任何与FLD02 有关的操作码,那么
程序会正常运行完毕,不会有报错。
这时,FHS02ILE 调用了程序FHS01ILE 之后,程序中原有的接口参数的数据就可
能因为这次调用程序而发生错位,从而导致数据的错误、混乱。数据的错误、混乱其实
还不是最大的问题,更大的问题在于“这时我们不知道数据已经出错了”。解决之道,
也是如上所说,对于调用频繁,且入口参数较多的公共程序,考虑将其入口参数写成一

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值