1.1.1.5
KLIST名
·KLIST名是分配给键字字段列表的符号名。
1.1.1.6 Labels
标号名也是符号名,它指出程序中特殊位置(例如,这个名字可以分配给TAG或ENDSR操作)。
1.1.1.7
命名常量
命名常量是分配给常数的符号名。
1.1.1.8
PLIST名
PLIST名是分配给参数表的符号名。
1.1.1.9
记录名
记录名是分配给外部描述文件的记录格式的符号名。以下是RPGⅣ程序中记录名的附加规则:
记录名仅存在于程序中的一个文件中。
注:关于如何取消这个限制的内容参看3.3.2.21“RENAME(外部-格式:内部-格式)”。
1.1.1.10 子程序名
此名是在BEGSR操作中用因子1定义的。
1.1.1.11 表名
下面是关于表名的一些附加规则 ·表名包含3-10个字符 ·表名必须以TAB开头 1.1.2
RPGⅣ的特殊功能字/保留字
下面是在程序内具有特殊功能的保留字: ·下面的保留字允许程序员访问工作日期或其中一部分,以便在程序中使用;
UDATE
UDAY
*DATE *DAY UMONTH *MONTA UYEAR *YEAR
·下面的保留字给报表编页号,给记录排顺序号,或给输出字段排顺序号。 PAGE
PAGE1-PAGE7
·图型常量是无长度规定的文字常量:
*BLANK/*BLANKS *ALLX’x1..’ *ZERO/*ZEROS *ALLG’0K1K2i’ *HIVAL *ALL’X..’ *LOVAL *NULL *ON *OFF
·下面的保留字允许把指示器做为数据来引用: *IN *INXX
·用于日期和时间特殊字: *DMY *EUR *HMS ·用于传送的特殊字:
*ISO
*JIS
*JUL
*MDY *YMD *USA
*ALTSEQ *EQUATE *FILE *FTRANS *PLACE允许在输出记录中重复放置字段。(详细信息请见3.7.4.2.3) *ALL允许在外部描述文件中定义的全部字段做输出。(关于*ALL的更多信息参看“图形常量规则”)。 用在内部功能的特殊字:
*ALL *NULL
·用于参数传递的特殊字:
*OMIT 1.1.3 用户日期特殊字
用户日期的特殊字(UDATE,*DATE,UMONTH,*MONTH,UDAY,*DAY,UYEAR,*YEAR)允许程序员为程序在运行时提供一个日期。用户日期特殊字访问在作业描述中说明的工作日期。用户日期可以在输出时写出,UDTAE和*DATE可以用控制说明中的Y编辑码指定写出的格式。(有关作业日期的描述参看&wrkmgmtl)。
1.1.3.1
用户日期的规则
使用用户日期时,记住如下规则:
在输出规范表的30-43列上指定UDATE时,打印一个6个字符的数字日期字段。当用相同格式指定*DATE时,打印一个8个字符的数字日期字段,(4位年部分),这些特殊字可以用三种不同格式: 月/日/年 年/月/日 日/月/年
在控制规范表中,使用键字DATEDIT说明所用的编辑码,如果没有指定这个键字,则缺省值为*MDY(月日年)。
在输出规范表中30-43列上指定UMONTH,*MONTH,UDAY,*DAY和UYEAR时,打印一个2位长的日期字段。*YEAR打印一个4位长的日期字段。用UMONTH或*MONTH仅打印月,用UDAY或*DAY仅打印天,UYEAR或*YEAR仅打印年。
如果在输出规范表中44列上指定一个Y编辑码,可以编辑UDATE和*DATE的打印格式。在控制规范表中键字DATEDIT决定格式和分隔符,例如12/31/88、31.12.88、12/31/1998。
在输出规范表中不能用Y编辑码来处理 UMONTH,*MONTH,UDAY,*DAY,UYEAR和*YEAR。
不能更改用户日期字段,即它们不能用做下面内容: —计算中结果字段 —作为PARM操作的因子1 —作为LOOKUP操作的因子2下标 —在输出规范表上使用写后清 —作为输入字段
用户日期的特殊字可用于计算规范表中的数字字段操作的因子1和因子2,用户日期字段不是日期数据类型字段而是数字字段。 1.1.4
PAGE、PAGE1-PAGE7
PAGE用于给报表编页号,给文件的输出记录排序号,或给输出字段排序号,它不能删除一页。
有8个PAGE字段用来满足不同类型的输出页号,或者不同打印文件的编号需要。 在输出规范表中30-43列或输入规范表或计算规范表中指定PAGE字段。
1.1.4.1
PAGE、PAGE1-PAGE7的规则
使用PAGE字段时,请记住如下规则: ·在输出规范表中指定PAGE字段时,不需在别处定义,它被认为是一个4位数字长 的无小数位的数字型字段。 ·页的记数除非另外指定,都从0001开始,每个新页自动加1。 ·如不是从第1页开始,设置PAGE字段的值比起始页号小1。例如,如果页号是从 24页开始,则在PAGE字段键入23。PAGE字段可以是任意长,但必须是无小数 位的数(见图1)。 ·页号可在作业的任意点上重新开始。以下方法可以重新设置PAGE字段: —指定写后请(输出规范表的45列) —指定PAGE字段作为计算规范表中某个操作的结果字段 —指定输出指示器(在输出规范字段),(见图2)。当指示器为ON时,PAGE字 段重新置为1,由于总是写PAGE字段,输出指示器不能用来控制PAGE字段的打 印。 —指定PAGE字段作为输入字段,见图1。
在指定编辑码,编辑字或日期格式(52列的P/B/L/R)来打印PAGE字段时,前置零
可以自动抑制(用Z编辑码),编辑和日期格式能复盖前置零的抑制。在输入和计算规范表中指定PAGE字段时,它可以看作是输出规范表上的一个字段名并且不自动抑制前置零。
*...1....+....2....+....3....+....4....+....5....+....6....+....7... IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................ I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr.... IINPUT PG 50 1 CP
I 2 5 0PAGE
图1 页记录描述
*...1....+....2....+....3....+....4....+....5....+....6....+....7... OFilename++DF..N01N02N03Excnam++++B++A++Sb+Sa+........................... O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat O* 当指示器15为ON时,PAGE字段在打印之前设为0然后加1。 O* 当指示器15为OFF时,在它打印之前内容加1。 O*
OPRINT H L1 01 O 15 PAGE 1 75
图2 重置PAGE字段为零
1.2 第二章 编译指令
编译程序指令语句/TITLE、/EJECT、/SPACE、/COPY用来为编译清单指定标题信息,控制空行,在编译时从其它文件成员插入记录。编译程序指令语句必须放在任何编译时的数组或表记录,传输记录和交替分配顺序记录(也就是,**Records)之前。 1.2.1
/TITLE(7-12列)
使用编译程序指令语句/TITLE规定标题信息(例如安全级或标题),它出现在编译清单每页的开头,登记项如下: 列 项 7-12 /TITLE 13 空格 14-100 标题信息
一个程序可以包含多个/TITLE语句,每个/TITLE语句提供标题信息直到另一个/TITLE
语句出现。一个/TITLE语句必须在第一个RPGⅣ规范表中,它用来打印编译清单的第一页信息。由/TITLE语句指定信息与编译程序标题信息一起打印出来。
/TITLE语句可以引起在打印标题之前跳一页,/TITLE语句本身不在编译清单中打印。 1.2.2
/EJECT(7-12列)
列 项 7-12 /EJECT 13-49 空格 50-100 注释
在7-12列上的/EJECT指出随后规范表将在编译清单的新一页开始,13-49列必须是空格,其余部分用来做注释。如果假脱机文件已经在一个新页的开头。/EJECT就不再开始下一页,/EJECT不在编译清单中打印。 1.2.3
/SPACE(7-12列)
使用编译程序指令/SPACE可以控制编译清单中源语句段间的空行: 列 项 7-12 /SPACE 13 空格 14-16 1到112的正整数,定义在编译清单中的空行数。这个数字必须左对齐 17-49 空格 30-100 注释
如果在14-16列上指定数大于112,则用112做/SPACE的值。如果指定值大于当前页上所剩余的行数,则在下一页的顶部开头。
/SPACE并不在编译清单中打印,但可以由指定的空行数代替。在不同规范表类型之间间隔,由/SPACE规定的空行数再加两行。 1.2.4
/COPY(7-12列)
/COPY 指令使在文件编译时从中取记录插入到/COPY指出的地方。插入的文件可以包含除/COPY以外的任何合法规范表。 /COPY语句是以如下方式录入的: 列 项 7-11 /COPY 12 空格 13-49 标识被拷贝的成员位置,格式如下: 库名/文件名成员名(RPGⅣ AS/400环境)。必须规定成员名。如果 没给文件名,则假定为QRPGLESRC。如果没指定库名,则在库列表中 查找文件,在库列表中查找这个成员的所有源文件直到找出或完成查 找。如果指定库名,则必须指定文件名。 50-100 注释
图3给出了/COPY的一些例子。
C/COPY MBR1 1
I/COPY SRCFIL,MBR2 2
O/COPY SRCLIB/SRCFIL,MBR3 3
O/COPY \"SRCLIB!\"/\"SRC>3\
图3 /COPY指令的一些例子
1、从源文件QRPGLESRC中拷贝成员MBR1,用当前库列表查找文件QRPGLESRC。 2、从文件SRCFIL中拷贝成员MBR2,用当前库列表查找文件SRCFIL。注意用逗号 (,)把文件名、成员名分开。
3、从库SRCLIB中的SRCFIL文件中拷贝成员MBR3。
4、从库“SRCLIB!”中的“SRC>3”文件中拷贝成员“MBR ”。
在编译期间/COPY的结果
1.2.4.1
在编译期间,被指定的文件成员合并进入到程序中/COPY语句出现的地方。所有的/COPY成员将出现在COPY成员表中。
1.3 第三章 程序周期
RPGⅣ编译程序支持RPGⅣ程序的逻辑部分,这一编译程序支持的逻辑称为程序周期 或逻辑周期。程序周期是对每一个读入的记录,程序要进行处理的一系列有序的步骤。 对记录的读或写在源程序规范表的编码中不需要明显的指定。在源程序编译时,RPGⅣ编译程序能够支持这些操作的逻辑顺序。根据你编写的不同规范表,程序可以确定用或不用周期中的每一步。
主文件(文件描述规范表的18列上标识P)和次文件(在18列上标识S)指定的输入是由程序周期控制的,一个全过程文件(在18列上标识F)指出,输入是由程序规定的计算操作控制的(例如,READ和CHAIN) 一个程序可以由以下组成: ·一个主文件和,可选一个或多个次文件 ·仅由全过程文件 ·由一个主文件,可选的次文件和一个或多个全过程文件,其中某些输入是由周期控制,其它输入由程序控制。 ·没有文件。(例如,输入可能来自一个参数列表或一个数据区数据结构)。 1.3.1
一般RPGⅣ程序周期
图4给出了RPGⅣ程序周期中一般流程的具体步骤。一个程序周期从第1步开始继续到第7步,然后再从第1步开始。
程序首次和最后一次通过RPGⅣ周期与正常周期有些不同,在读第一条记录第一次通过该周期之前,程序解释传递给它的参数,写出用1P指示器作条件的记录,做文件和数据初始化,处理无条件指示器或所有否定条件指示器有关的标题或者明细输出。例如,在读第一个记录之前,打印的标题能包括常量或页标题信息或保留字的字段,象*DATE和PAGE。另外,在第一个周期中,程序绕过总计计算和总计输出步骤。
在程序最后一次通过周期期间,这时,没有记录可读,LR指示器(最后一条记录)和L1到L9指示器(控制级)设为ON。做文件和数据的清理工作。
开 始 1 处理标题和 详细行
2 取得输入 记 录 3 处理总计 计算 4 处理总计 输 出 5 LR为 是 ON? 程序结束 不是 6 传送字段
7 处理详细 计算
图4 RPGⅣ程序逻辑周期
1.处理全部的标题和明细行(输出规范表中17列标识H或D) 2.读取下一个输入记录并把记录标识指示器和控制级指示器置为ON。 3.处理总计计算,总计计算是由L1-L9或LR指示器指出或登记一个L0项。 4.处理全部的总计输出行(输出规范表17列标识为T)。 5.检查LR指示器是否为ON,如为ON,程序结束。 6.所选择的输入记录的字段从记录中传送到处理区,字段指示器置为ON。 7.对在周期开始时读入的记录数据做所有明细计算(在计算规范表上7和8列没有控制级指示器作条件)。
1.3.2
详细的程序周期
在上节中介绍了基本的逻辑周期,下图解释了详细的逻辑周期。
开 始 1 ·设RT指示器为OFF ·参数分解
2 程序是 No 第一次调用? Yes 把结果字段传送给 5 *ENTRY PLIST的因子1 3 *INIT ·运行程序初始化 ·做数据结构和子字段的初始化 ·恢复外部指示器(u1-u9)和用户 日期字段 ·打开文件 ·装入数据区数据结构、数组和表 ·把结果字段传送给*ENTRY PLIST 的因子1 ·运行初始化子例程*INZSR ·为RESET操作存数据结构和变量 4 *DETL ·处理标题和详细输出 ·处理取溢出行 ·设置1P *GETN 5 No 有无H1-H9 8 为ON? 5 A Yes 设暂停指示 发信息 器为OFF No 5 B 回答是 否为撤消? Yes 6 No 撤消及转储? 7 Yes 做转储 36 8 设置记录标识指示器L1-L9 10 9 LR Yes 设置 29 ON L1-L9 No 12 11 RT Yes 把因子2移到*ENTRY ON PLIST的结果字段 13 返回调用者 14 No 主文件? 29
15 ·在第一个周期,从主文件和 每个次文件中读第一个记录 ·在其它周期,如果需要,从 最后一个处理的文件中读输入 记录 17 No 16 文件结束? 确定记录类型和顺序
Yes 18 无定义记录 Yes 类型和顺序错误 No 19 RPG例外/错误处理程序 21 20 发布 Yes 初始化处理的 24 FORCE? FORCE文件 No 23 22 规定 Yes 匹配字段例程 24 匹配字段? No 25 24 LR Yes 设LR为ON 设为ON? L1-L9为ON 26 No 为选择的记录设 记录标识指示器 No 27 控制中断? Yes 28 29 28 Yes ·设相应的L-L9 ·保存控制字段 29 No 做总计? 30 Yes *TOTC 做总计计算 31 *TOTL 做总计输出 返 回
32 LR Yes 33 Yes ON? 暂停指示器 41 No 42 34 35 *TERM 溢出指示器 *OFL例程 LR Yes·写锁住的数据区 Yes ON? 结构 No ·重设外部指示器 43 36 设MR指示器为 No *CANCL ON或OFF ·关闭文件 ·解锁由这个程序 44 锁住的数据区 37 Yes ·使从最后记录读的数据可用 暂停指示器? ·设字段指示器ON或OFF 45 规定 Yes 46 38 先行字段? 先行例程 把因子2传送 47 No 给参数 39 *DETC做详细计算 设置返回码,如非 正常结束,发布逃 4 避信息 40 返回给调用者 注: 表示RPG例程(详细的内容看图下面的解释)
图5 详细的目标程序周期
1.3.2.1
详细的RPGⅣ目标程序周期
图5给出了详细的周期流程的具体步骤,以下的序号与图中号码相对应,例程是由图8和图6的流程图描述。 1.RT指示器置为OFF。如果说明了*ENTRY PLIST则分解参数。 2.检查程序是否是第一次执行,如果是,则做程序初始化,如果不是,则把结果字段传送到*ENTRY PLIST的PARM语句的因子1并转至第5步。 3.程序在*INIT处做初始化,此过程包括:数据结构和子字段的初始化,建立用户日期字段;打开文件,装入全部的数据区数据结构及数组和表,把结果字段传送至*ENTRY PLIST的PARMS语句的因子1中;运行初始化子程序*INISR,为RESET操作存储结构和变量,文件按在文件描述规范表中的顺序打开。 4.在读第一个记录之前写标题和明细行(输出规范表的17列上标识H或D)。同时也处理标题和明细行。如果说明了条件指示器,则设置适当的指示器。如规定了取溢出逻辑且溢出指示器置为ON,则写出相应的溢出行,如果规定了文件转换,那么做标题、明细行和溢出输出。如果ENDSR操作的因子2的值为*DETL,则这步为程序的返回点。 5.检测暂停指示器(H1-H9),如果全部为OFF,程序转至步骤8。在程序任何期间,暂停指示器都可置为ON,如ENDSR操作的因子2为*GETIN,则这步为程序返回点。 a.如有暂停指示器为ON,则向用户发送信息; b.如果回答为继续,暂停指示器为OFF,程序返回5,如回答为取消,则继续6。 6.如果回答是取消且转储,程序到第7步,否则,转至36。 7.程序发出一个转储输出并转到36。 8.所有记录标识指示器、1P、控制级(L1-L9)指示器置为OFF,全部溢出指示器(OA-OG,OV)为OFF,除非在处理明细计算或明细输出时,它们已是ON,其它为ON指示器仍保持ON。 9.如LR为ON,则程序继续做10,如为OFF,程序转至11。 10.设置相应控制级指示器为ON,转至29。 11.如RT为ON,继续做12,如为OFF,则转至14。 12.把因子2传送到*ENTRY PLIST参数的结果字段。 13.如果RT为ON程序返回调用者。 14.如果程序中有主文件,则继续15,否则转至29。 15.在第一个周期中,从主文件和每个次文件中读第一个记录,在输入记录中做文件转换,在其它程序周期中,从最后处理的文件中读记录。如果文件是由记录地址文件处理,则在记录地址文件中的数据定义了要检索的记录。如果在最后处理记录中说明先行字段,记录可能已在存储器中,这时,可能无读操作。 16.如果刚读的文件到了文件末,则转至20,否则,程序继续17。 17.如果记录已从文件中读出要确定记录的类型和顺序(输入规范表的17-20列)。 18.检查记录类型是否定义,顺序是否正确,如果类型未定义或者顺序不正确,程序继续19,否则转至20。 19.控制转给RPGⅣ异常/错误例程。 20.检测先前周期中是否处理过FORCE操作,如果处理过,程序选择处理的文件(21步)并转到匹配字段的处理步(22、23步),这个分支的处理是由于所有用FORCE操作处理的记录都是用匹配记录(MR)指示器为OFF处理的。 21.如果先前周期发出FORCE操作,则在保存刚读文件的匹配字段以后,程序选择被强制的文件进行处理。如果此强制文件在文件末,正常主文件/次文件多文件逻辑选择下一个记录处理,程序转至24。 22.如果指定匹配字段,程序继续23,否则转至24。
23.匹配字段例程接收控制(详细内容请看1.3.2.2.1的内容) 24.在文件描述规范表19列上指定了E的文件的所有记录处理完以及所有匹配的次记录处理完时,LR置为ON。如果LR没设为ON,,续执行26。 25.置LR指示器为ON,设置全部L1-L9指示器,继续29。 26.对选择要处理的记录,记录标识指示器置为ON。 27.检查所选的要处理记录是否导致一个控制中断,当被处理记录中控制字段的值和最后处理的记录中的控制字段中的值不同时就产生一个控制中断,如果没有中断,转至29步。 28.当发生控制中断时,相应的控制级指示器置为ON,所有低级控制指示器也为ON,程序保存这些控制字段的内容以备下一次比较使用。 29.检测是否应该执行总计计算和总计输出,总计是在LR为ON时来做。如果在输入规范表中没有说明控制级,在第一个周期中绕开总计,在第一周期以后,在每个周期中都处理总计,如果在输入规范表中说明了控制级,绕过总计,直到遇到处理有控制字段的第一个记录为止。 30.处理由控制级项所指出的全部总计计算,如果ENDSR操作的因子2为*TOTL时,这步为程序返回点。 31.处理总计输出。如果说明了取溢出逻辑以及各文件相关的溢出指示器(OA-OG,OV)为ON,则写溢出行。如说明了文件转换,执行所有的总计输出和溢出行。如果ENDSR的因子2的值为*TOTL 这步为程序返回点。 32.如LR为ON,处理33步,否则至41步。 33.测试暂停指示器(H1-H9)。如果任一个指示器为ON,转至36步(异常结束)。如果指示器为OFF,继续34,如在计算中使用RETURN操作,程序在此操作执行后转到33步。 34.如LR为ON,程序处理35步。如不为ON,转至38步。 35.为定义规范表定义的TOFILE键字写出全部数组或表,并写出所有上锁的数据区数据结构。如需要,则转换输出数组和表。 36.关闭所有打开的文件。解锁全部已上锁的还没有被程序解锁的数据区。如果ENDSR的因子2是*CANCL,这步是返回点。 37.测试暂停指示器(H1-H9),如有指示器为ON,转至39步(异常结束),如果为OFF处理38步。 38.因子2字段传送给*ENTRY PLIST中PARM的结果字段。 39.设置返回码,1=LR ON,2=错误,3=暂停 40.控制返回给调用者。
注:32-40步为正常的结束例程;对一个异常结束不做34、35步。 41.测定溢出指示器(OA-OG,OV)是否为ON。如为ON,处理42,否则,转至43步。 42.溢出例程接收控制(详细信息请看1.3.2.2.2)。如果ENDSR操作的因子2为*OFL则这步为程序的返回点。 43.如果是一个多文件的程序且被处理的记录是匹配记录则MR指示器是ON并在处理匹配记录的整个周期中MR保持为ON,否则MR设为OFF。 44.处理最后读进记录中的数据,设置的字段指示器为ON。 45.如果说明先行字段,则处理46步,否则转至47步。 46.先行例程接收控制(详细信息请看1.3.2.2.3)。 47.执行明细计算。如果ENDSR操作的因子2为*DETC,则这步为程序返回点。程序转至第4步。
1.3.2.2
初始化子程序
参考图5,看关于RPGⅣ初始化子例程的详细说明。
这个在程序初始化时运行的特殊子例程是由BEGSR操作的因子1为*INZSR定义的,仅一个子例程可以定义为初始化子例程,它在程序周期中程序初始化步结束时被调用。(也就是说,在数据结构和子字段初始化后,检索外部指示器和用户数据字段。打开文件,装入数据区数据结构、数组和表,并将PARM结果字段传送至*ENTRY PLIST的因子1中),*INZSR不能作为文件/程序错误/异常子例程。
如果程序是以LR为OFF结束,初始化子例程在调用下一个程序时不能自动运行,这是因为子例程是程序初始化步骤的一部分。
初始化子例程除了在程序初始化时被调用以外,和程序中其它子例程是一样的,它可以用EXSR或CASxx调用,也可以调用其它子例程或其它程序。除了RESET操作外,在子例程中的任何合法操作在初始子例程中也是合法的,因为用于RESET的值要在初始化子例程运行之后才定义。
在初始化子例程期间,任何变量的修改都会影响该变量在RESET操作的值。字段的缺省值可以在记录格式中定义为初始化子例程中设置的值,当要用缺省值时,使用RESET操作。初始化子例程也可检索一些诸如1P输出的当前时间的信息。
匹配字段例程 No 多文件处理?
1
2 Yes 确定要处理的文件 4 3 匹配字段 Yes RPG异常/错误 顺序错误? 处理程序
5 No 把匹配字段传送 到匹配字段区
图6
溢出例程 先行使程
返回 1 Yes 1 前面写出过溢出行? No 2 处理溢出输出 2 读这个文件 的下一条记录 抽取先行字段
返回 返回
RPGⅣ的匹配字段,溢出和先行子例程的详细流程
1.3.2.2.1匹配字段例程
图6给出了匹配字段子例程的步骤,以下解释中项号与图中号码一致。 1.如果处理多文件,则继续处理第2步,否则,转至3。 2.测试在保持区中匹配字段的值,来决定接下来处理哪个文件。 3.RPGⅣ程序从匹配文件抽取匹配字段。然后做顺序检查。如果匹配字段是按顺序的,则程序转至5。 4.如果匹配字段无序,则PRGIV异常/错误处理例程接收控制。 5.匹配字段移入这个文件的保持区,对每一个有匹配字段的文件提供一个保持区。再根据匹配字段中的值来选择要处理的下一个记录。
1.3.2.2.2 溢出例程
图6给出溢出例程的步骤,以下解释中的项号与图中号码一致。 1.程序测试以前是否用取溢出逻辑写出过溢出行(1.3.2节中的第20步)。如果以前写过,则程序转到指定的返回点,否则,继续处理2。 2.测试溢出指示器限制的全部输出行,并且写出条件限制的溢出行。
取溢出例程允许程序员修改基本溢出逻辑防止打印溢出一页,且使用户在一页中尽可能多打印一些内容。在一般的程序周期中,RPGⅣ程序仅在总计输出后立即检查一次,查看溢出指示器是否为ON。当指定取溢出功能时,RPGⅣ程序要检查规定了取溢出的每行的溢出情况。
对于一个打印文件来说,指定取溢出应在明细行、总计行或异常行的输出规范表的18列上标识F,取溢出例程不自动往前打下一页。
在输出期间,测试输出行的条件指示器决定该行是否写出。如果该行可写,并且18列标识为F,程序测试确定溢出指示器是否为ON。如为ON,取出溢出例程并做如下 : ·仅测试指定取溢出文件的溢出行的输出。 ·写出由溢出指示器做条件的全部总计行。 ·当跳行数少于当前打印机所在的由溢出指示器规定的行数时,往前跳至下一页。 ·写出由溢出指示器条件限制的标题行,明细行和异常行。 ·写出取溢出例程的行。 ·写出由程序周期控制写的明细行和总计行。
如果溢出例程用于OR关系中的每个记录,则OR行的18列上必须标识F。在同一规范行中,如果21-29列上指定溢出指示器,那么不能使用取溢出。如果上述情况发生了,则无法取溢出例程。
如果在一页上没有足够的空间打印由溢出指示器条件限制的明细行、总计行、异常行和标题行时,使用取溢出例程。要决定什么时候取溢出例程,必须研究所有可能的溢出条件,通过计算行和空间,就可估计出在每一个明细行、总计行和异常行溢出时发生的情况。
1.3.2.2.3 先行字段例程
图6表明先行字段例程步骤。以下的项号与图中号码一致。 1.读正被处理文件的下一个记录,但如果文件是组合或更新文件,则从当前处理记录中抽取先行字段。
2.抽取先行字段。
无主文件程序的结束
1.3.2.3
如果程序中不包含主文件,必须指定一种方法来结束程序: ·设置LR指示器为ON。 ·设置RT指示器为ON。 ·设置H1-H9指示器为ON。 ·说明RETURN操作码。
LR、RT、H1-H9指示器和RETURN操作码可以相互联合使用。
1.3.2.4
文件处理的程序控制
指定一个全过程文件来控制程序的全部或部分输入。全过程文件指出,输入是由程序说明的计算操作(例如READ、CHAIN)来控制的。当程序中说明一个全过程文件和一个主文件时,某些输入是由程序控制,其它输入是由周期控制的。说明全过程文件时,程序周期就存在,但在全过程文件的明细或总计计算时做文件处理。
文件操作码可以用来做程序控制输入。这些文件操作码在第22章4.3中介绍。
开始
执行标题操作 执行明细输出操作 如果抵达溢出行, 置溢出指示器为on
执行明细计算 设置结果指示器
置控制级
把周期开始选的记录中的数据 传送到处理域
指示器为off 置记录标识 指示器为off 溢出指示器为on吗?是的,执行溢出操作。
文件记录末?是的,置控制 级和LR指示器为on并跳到 总计计算,执行总计计算
读一个记录
LR指示器为on吗?是的,程序结束。
执行总计输出操作,如果达到 溢出行, 设置溢出指示器为on。
执行总计计算, 设置结果指示器
设置刚读的记录的记录标识 指示器为on
图7 程序员控制的程序周期内输入操作
No 顺序执行操作 异常/错误 1 2 3
Yes 如果说明了,建立文件 信息和程序状态数据结构 No Yes 设置指示器为on并 执行下一顺序操作 该操作有错误指示器? No Yes 控制转到INFSR或 执行INFSR或*PSSR? No 13 *PSSR子例程 14 是否指定返回点? 4 No Yes 返回到相应的返回点 Yes 重新执行当前的操作 状态码为1121-1126? 5 6 No No 15 渗透异常给该过程的调用者, 该过程下一点的详细情况见注释 是功能检查? Yes 给请求者发信息 7 8 No 继续执行 请求撤消吗? Yes No 撤消并转储输出? 9 Yes 发出转储输出 10 关闭文件解锁数据区 11 释放过程以使过程能再次被调用 12 设置返回并渗透功能检查
图8 RPGⅣ异常/错误处理例程的详细流程
1.3.2.4.1 异常/错误处理子例程
图8给出异常/错误处理例程的具体步骤。下面说明的项号与图中号码一致。 1. 用状态信息建立文件信息或过程状态数据结构。 2.如果异常/错误发生在一个73和74列规定了指示器的操作码上,则指示器设为ON控制返回到该计算中下一个顺序指令。 3.如果过程中有相应的异常/错误例程(INFSR或*PSSR)则转至13、 4.如果状态码为1121-1126,控制返回给计算中的当前指令,如果不是,则处理5。 5.如果异常是一个功能检查,则继续处理6,如果不是则转至15。 6. 请求者发一个信息,对交互作业,信息发给请求者,对批处理作业,信息发给QSYSOPR,如果QSYSOPR不是中断方式,发出一个缺省的响应。 7.如果用户响应是撤消过程,则继续处理8,否则,过程继续。 8.如果用户响应是撤消,但要转储输出,则继续处理9。如果不是,则转至10。 9.发出一个转储输出。 10.关闭所有文件并解锁数据区。 11.释放程序以使它能再次调用。 12.设置返回码,同时渗透功能检查。 13.控制转给异常/错误子例程(INFSR OR*PSSR) 14.如果在异常/错误子例程的ENDSR的因子2上指定返回点,程序转至规定的返回点。如果没有设返回点,则转至4,如果在ENDSR操作的因子2指定字段名,但内容不是RPGⅣ定义的返回点,(例如*GETIN或*DETC),程序转至6,不指出错误,而原始错误按因子2为空格那样处理。 15.如果没有请求处理异常,那么进行功能检查并且转至5,否则,根据处理的功能,在异常发生处后,控制转给第10步或下一个机器命令。
1.4 第4章 RPGⅣ的指示器
指示器是一个字节的字符型字段,其值为“1”(ON)或“0”(OFF),通常是用来指示操作结果或用于限制(或控制)一个操作的处理。
指示器是由规范表的登记项定义或由RPGⅣ程序本身定义,在规范表中定义的位置取决于指示器的作用,定义指示器用来给出计算和输出操作的条件。
RPGⅣ程序在程序周期指定的时间中设置或重设指示器,另外,大多数指示器的状态能由计算操作修改。除了MR、1P、KA-KN、KP-KY之外,所有指示器都能用SETON操作码设为ON。除MR和1P以外,所有指示器能用SETOFF操作码设为OFF。 本章分为如下几部分: ·在规范表上定义指示器 ·不在规范表上定义指示器 ·使用指示器 ·作数据引用的指示器 1.4.1
在规范表上定义的指示器
可以在规范表上指定下列指示器: ·溢出指示器(文件描述规范表的OFLIND键字) ·记录标识指示器(输入规范表的21、22列) ·控制级指示器(输入规范表的63、64列) ·字段指示器(输入规范表的69-74列) ·结果指示器(计算规范表的71-76列) ·*IN数组,*IN(xx)数组元素或*INxx字段(参考1.4.4节内容) 在程序中可以用已定义的指示器做条件操作。
1.4.1.1
溢出指示器
溢出指示器是由文件描述表中的OFLIND键字定义的。当打印了或通过了一页的最后一行则置为ON。有效的指示器是*INOA-*INOG,*IN01-*IN99,已定义的指示器可用于限制计算或输出操作,关于溢出指示器的详细描述及取溢出逻辑在“1.3.2.2.2的溢出子例程”中介绍。
1.4.1.2
记录标识指示器
记录标识指示器是在输入规范表中21和22列定义的。当选择相应的记录去处理时置为ON,然后,指示器用于限制某个计算和输出操作,记录标识指示器不必用特定顺序分配。 有效的记录标识指示器为: 01-99 L1-L9 U1-U8 H1-H9 LR RT
对一个外部描述文件,该指示器是可选的,但是,一旦指定,它遵循和程序描述文件同样的规则。
一般来说,用指示器01-99作为记录标识指示器,但是,控制级指示器(L1-L9)和最后记录指示器(LR)也可用。如果把L1-L9作为记录标识指示器,较低级指示器不自动置为ON。
当选择一个记录类型处理时,相应的记录标识指示器置为ON。所有其它的指示器设为OFF,但用一个文件操作码检索文件中记录用于详细和总计计算时除外。记录选定后,在输入字段传送到输入区之前指示器置为ON。新记录的记录标识指示器是在对老记录做总计期间为ON。因此,用老记录字段做总计时的计算不能用老记录的记录标识指示器来限制。在程序周期的任何时候,都可以置指示器为OFF。它们是在选择下一个主记录或次记录之前置为OFF的。
如果在计算规范表上使用文件操作码来检索一个记录时,该记录标识指示器在从文件中检索到记录时置为ON。在周期中相应点之前指示器都为ON。(看1.3.2.4的图)。因此,同一个文件中,可以有几个记录标识指示器和记录没找到指示器,如果在同一个周期内对同一文件发出几个操作,它们可同时置为ON。
1.4.1.2.1 配置记录标识指示器的规则
给程序描述文件的记录分配指示器时,记住如下规则: ·如果在所有记录类型上执行同样的操作,则可以把同样的指示器分配给两个或多个不同记录类型.要这样做,可以在21、22列上指定指示器,并用一个OR关系指定不同记录
类型的记录标识码。 ·指示器可以用AND关系,但是AND必须在该组的第一行出现,不能在AND行上规定记录标识指示器。 ·没定义的记录(在程序描述文件中23-46列没有说明记录标识码)使程序停止。 ·指示器可以说明为另一个记录类型的指示器,也可以做为字段指示器或作为结果指示器,不发出诊断信息,但是指示器的这种用法可能导致错误结果。
给一个外部描述文件中的记录分配记录标识指示器时,记住以下各点: ·AND/OR关系不能和记录格式名一起用,但同一个指示器可以发给多个记录。 ·记录格式名(不是文件名),必须在7-16列上指定。 记录标识指示器的例子见图9。
*...1....+....2....+....3....+....4....+....5....+....6....+....7... IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................ I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr.... I*
I* 如果记录读在一位上有S或A,记录标识指示器01为ON。 I*
IINPUT1 NS 01 1 CS I OR 1 CA
I 1 25 FLD1
I* 如果记录读在1-4位上有XYZA,记录标识指示器02为ON。 I*
I NS 02 1 CX 2 CY 3 CZ I AND 4 CA
I 1 15 FLDA I 16 20 FLDB I*
I* 如果记录读不符合01或02的要求,记录标识指示器95为ON。 I*
I NS 95
*...1....+....2....+....3....+....4....+....5....+....6....+....7... IRcdname+++....Ri........................................................ I*
I* 对外部描述文件,如果读ITMREC,则记录标识指示器10为ON, I* 如果读SLSREC或COMREC,则记录标识指示器20为ON。 I*
IITMREC 10 ISLSREC 20 ICOMREC 20
图9 记录标识指示器的例子
1.4.1.3
控制级指示器(L1-L9)
控制级指示器是在输入规范表中63、64列上定义的,把一个输入字段定义为一个控制字段,用它限制计算和输出操作,有效的控制级指示器L1-L9。
控制级指示器可定义一个输入字段作为控制字段。当读一个控制字段时,该控制字段中的数据和前一个记录中相同的控制字段进行比较。如果数据不同,发生控制中断,则分配给控制字段的控制级指示器置ON。这样可以用控制级指示器作为条件限制操作,也即只对读入的控制字段中有相同信息的所有记录进行处理。由于该指示器在总计时和第一次明细期间保持ON,所以它们也能用来限制总计打印(控制组的最后一个记录)或者明细打印
(控制组中第一个记录)。在读下一个记录前,控制级指示器为OFF。
读入含有控制字段的第一个记录之后,能发生控制中断,这个记录中的控制字段与含有十六进制零的存储器中一个区域比较,由于来自两个不同记录的字段不能比较,则在这个周期内绕过总计计算和总计输出操作。
控制级指示器按重要程度的顺序排列,L1最低,L9最高。作为控制中断的结果,一个较高级指示器为ON时,所有较它低级的指示器设为ON。如果定义了低级指示器,则它们仅可用于程序中。例如,由于控制中断,L8为ON,则L1-L7为ON,当输入文件是文件末时,则LR置ON,LR被认为是最高控制级指示器,它强迫使L1-L9均为ON。
你也可以把控制级指示器定义做记录标识或结果指示器,以这种方式使用它们时,当较高级指示器置ON时,较低级指示器的状态不变。例如,L3做为结果指示器,如果L3置为ON,则L1和L2的状态不变。
控制字段相对于其它字段的重要性在于它能决定如何分配控制级指示器。例如,要求小计的数据应该比最后总计所需数据的控制指示器级别低,如果一个部门是由许多雇员组成,则含有部门号的控制字段应该有比含有雇员号的控制字段较高的控制级指示器(看1.4.1.3.1中的图10)。
1.4.1.3.1 控制级指示器规则
当你分配控制级指示器时,请记住: ·仅可为主文件或次文件指定控制字段 ·不可以为全过程文件,二进制字段或先行字段指定控制字段 ·当在输入规范表的49-62列上指出数组名时,不能使用控制级指示器,但是可以把控制级指示器和数组元素一起使用。 ·控制级比较操作按找到的顺序进行,而不管它们来自哪个文件。 ·如果在不同的记录类型或不同的文件上使用相同控制级指示器,与指示器相联系的控制字段必须长度相同(看图10)。但仅要求在类型上匹配的日期、时间、时间标记字段除外,(就是说,它们可能是不同格式)。 ·控制级指示器的字段长度即为记录中一个控制级指示器长度。例如,在记录中,L1有10字节的字段长,则L1的控制级指示器的字段长为10个字节。 ·分离控制字段的指示器长度为所有相关字段的总和。假如L2是由3个字段组成的分离控制字段,长度分别为12、2和4个字节,那么L2的控制级指示器字段长度为18个字节。 ·如果多个记录使用相同控制级指示器,那么指示器的字段长仅为一个记录长,而不是所有记录的长度和。 ·在程序内,全部控制级指示器的控制字段长总和不能超过256字节。 ·分配给不同控制级指示器的控制字段的记录位置可以在相同记录类型上重迭(看图11)。对于要求控制或匹配字段的记录类型,控制或匹配字段的总长不多于256。例如,在图11中,分配给控制级的是15个字节。 ·在控制级操作中,可以忽略字段名。因此,分配给同样控制级指示器的不同记录类型的字段可以有相同名。 ·控制级可按任意顺序写,L2可出现在L1之前,不必分配所有较低级控制指示器。 ·如果文件中不同记录类型没有相同数目的控制字段,能产生不需要的控制中断。 图12表示了如何避免不需要的控制中断。
*...1....+....2....+....3....+....4....+....5....+....6....+....7... A* EMPLOYEE MASTER FILE -- EMPMSTL
A R EMPREC PFILE(EMPMSTL) A EMPLNO 6 A DEPT 3 A DIVSON 1 A*
A* (ADDITIONAL FIELDS) A*
A R EMPTIM PFILE(EMPMSTP) A EMPLNO 6 A DEPT 3 A DIVSON 1 A*
A* (ADDITIONAL FIELDS)
*...1....+....2....+....3....+....4....+....5....+....6....+....7... IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................ I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr.... I*
I* 在这个例子中,对三个字段定义控制级指示器,控制字段名(DIVSON, I* DEPT,EMPLNO)。给出相对的重要性。DIVSON是最主要的,使用最 I* 高的控制级(L3),DEPT比DIVSON低,分配给它L2,EMPLNO有 I* 最低级的控制级指示器L1。 I*
IEMPREC 10
I EMPLNO L1 I DIVSON L3 I DEPT L2 I*
I* 相同的控制级指示器能用于不同的记录类型,但同一指示器的控制字段必须 I* 有同样的长度,对外部描述文件中的记录,字段的属性在外部描述中定义。 I*
IEMPTIM 20
I EMPLNO L1 I DEPT L2 I DIVSON L3
图10 控制级指示器
控制字段1 · 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 · · 控制字段2
一共有15个位置分配给了控制级
图11 重迭控制字段
(L2) (L2) (L1) Sale
Sale记录 Item记录
*...1....+....2....+....3....+....4....+....5....+....6....+....7... IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................ I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr.... ISALES 01
I 1 2 L2FLD L2 I 3 15 NAME IITEM 02
I 1 2 L2FLD L2 I 3 5 L1FLD L1 I 6 8 AMT
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq.. C* 当读Salesman记录时,指示器11设为ON。
C 01 SETON 11 C* 当读item记录时,指示器11设为OFF,允许发生正常的01控制中断。 C 02 SETOFF 11 C 02AMT ADD L1TOT L1TOT 5 0 CL1 L1TOT ADD L2TOT L2TOT 5 0 CL2 L2TOT ADD LRTOT LRTOT 5 0 C*
*...1....+....2....+....3....+....4....+....5....+....6....+....7... OFilename++DF..N01N02N03Excnam++++B++A++Sb+Sa+...........................
Sale
Sale
总数
号码 名字
号码 item名
1 2 3 5 1 2 3 5 6 8
O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat OPRINTER D 01 1 1 O L2FLD 5 O NAME 25 O D 02 1 O L1FLD 15 O AMT Z 15
O* 下个item记录引起L1控制中断,如果指示器11为ON,不打印总计输出。 O* 对item记录做明细计算。
OFilename++DF..N01N02N03Excnam++++B++A++Sb+Sa+........................... O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat O T L1N11 1
O L1TOT ZB 25 O 27 '*' O T L2 1
O L2TOT ZB 25 O 28 '**' O T LR 1
O LRTOT ZB 25
不需要的控制中断表示的输出 正确的输出
20
20
02
JANE DOE
100 100
101
6 2 8 3 3 不需要的 控制 中断
100 100
101
6 2 8 3 3
02
JANE DOE
01
JOHN SMITH
100 100
101
3 2 5 4 4 9 不需要的 控制 中断
100 100
101
3 2 5 4 4 9
01
JOHN SMITH
11 11
图12
如何避免不需要的控制中断
一般情况下,不同的记录类型有相同数目的控制字段。但是,有一些应用需要在某些记录中有不同的控制字段。
推销员记录仅有一个L2的控制字段,而item记录则有L1和L2两个控制字段。如果用正常的编码,由推销员记录后的第一个item记录生成一个不需要的控制中断,这个是由紧跟在推销员记录后的L1控制中断识别出来的,并在推销员记录的下一行上打印一个星号。 数字型控制字段以区位十进制格式比较,压缩型数字输入字段长度是由下列公式决定: d=2n-1
d为该字段中数字个数,n为输入字段长度。压缩数字字段中的数字个数总是奇数,因此当压缩型数字字段和区位十进制数字字段比较时,区位字段的长度必须是奇数。
当比较有小数位的数字型控制字段来确定是否发生控制中断时,总把它们作为整数对待,例如,3.46认为是346。
如果规定字段为数字型时,仅检查正数值来确定是否出现控制中断,即字段总是认为正的。例如,-5被认为是+5。
日期和时间字段在比较之前要转换成*ISO格式。 图形数据与十六进制值比较。
1.4.1.3.2 分离的控制字段
当把同样的控制级指示器分配给一个输入记录中的多个字段时,要形成分离的控制字段。对程序描述文件,有同样控制级指示器的字段由程序员在输入规范表上指出的顺序组合组成,且被看作是一个单独的控制字段(见图13)。把定义的第一个字段放在控制字段的高位(最左边),而最后一个定义的字段放在控制字段的低位上(最右边)。
*...1....+....2....+....3....+....4....+....5....+....6....+....7... IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................ I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr.... IMASTER 01
I 28 31 CUSNO L4 I 15 20 ACCTNO L4 I 50 52 REGNO L4
图13 分离的控制字段
对外部描述文件,有相同控制级指示器的字段以在数据描述规范中(DDS)描述的顺序组合,而不是按在输入规范表上所指出字段的顺序组合,例如,如果在DDS中描述的字段是按下列顺序:
EMPNO DPTNO REGNO
且假定在输入规范表上这些有相同控制级指示器字段,按下列顺序说明:
REGNOL3
DPTNOL3 EMPNOL3
字段还是按下列顺序组合形成一个分离的控制字段:EMPNO,DPTNO,REGNO。 分离控制字段的一些特殊规则是: ·对于一个控制级指示器,可以把某个记录类型中的一个字段分开,如果字段名不同就不能在别的记录类型中分开。但是,无论分开或不分开的字段长度,在所有类型中都必须是相同的。 ·对于不同的记录类型,如果字段名不同,你可以改动一个分离的控制字段的部分长度。但是,总长度是相同的。 ·一个分离的控制字段可以由压缩十进制字段和区位十进制字段组合构成,只要字段长度是(数字或字符)相同的。 ·对在一个记录类型中的分离的控制字段的所有部分,必须配置相同的字段记录关系指示器且它必须在续行上定义。 ·当分离控制字段包含日期,时间,时间标记字段时,所有字段必须是同一类型。 图14给出上述规则的例子。
*...1....+....2....+....3....+....4....+....5....+....6....+....7... IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................ I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr.... IDISK BC 91 95 C1 I OR 92 95 C2 I OR 93 95 C3 I
I* 分离的控制字段的所有部分必须分配同一控制级指示器,且必须有相同的 I* 字段记录关系项。 I*
I 1 5 FLD1A L1 I 46 50 FLD1B L1 I 11 13 FLDA L2 I 51 60 FLD2A L3 I 31 40 FLD2B L3 I 71 75 FLD3A L4 92 I 26 27 FLD3B L4 92 I 41 45 FLD3C L4 92 I 61 70 FLDB 92 I 21 25 FLDC 92 I 6 10 FLD3D L4 93 I 14 20 FLD3E L4 93
图14 分离控制字段的特殊规则
在95列上标识有1的记录有两个分离的控制字段:
1.FLD1A和FLD1B 2.FLD2A和FLD2B
在95列上用“2”标识的记录有三个分离的控制字段: 1.FLD1A和FLD1B 2.FLD2A和FLD2B 3.FLD3A、FLD3B和FLD3C
在95列上用“3”作标识的第三个记录类型也有三个分开的控制字段: 1.FLD1A和FLD1B 2.FLD2A和FLD2B 3.FLD3D和FLD3E
1.4.1.4
字段指示器
字段指示器是由输入规范表上69和70,71和72或73和74上内容定义的,有效的字段指示器为:
01-99 U1-U8 H1-H9 RT
你可以用一个字段指示器来检测规定的字段或数组元素是正的、负的、零,还是空格,69-72列仅对数字型字段有效,73、74列对数字型或字符型有效,当数字型输入字段是正时,在69和70列的指示器为ON;如为负时,在71和72列上指定指示器为ON。当数字型为零或字符型空格时,则73、74列指示器为ON。可以使用字段指示器限制计算或输出操作的条件。
当字段或数组元素中的数据从记录中取出且它表示的条件在输入记录中出现时,字段指示器设为ON,在读入同类型的另一个记录并且它的条件在输入记录中不出现时,此指示器才变为OFF或在该指示器作为一个计算的结果被置为OFF。
可以使用暂停指示器(H1-H9)作为字段指示器,检查读到程序中去的字段或数组元素是否有错。
1.4.1.4.1 配置字段指示器的原则
在配置字段指示器时,记住以下事项: ·程序开始时,正、负、零或空格的指示器置为OFF状态,在刚读的记录上检测的字段满足条件(正、负、零或空格)时才置为ON。 ·字段指示器不能与整个数组或先行字段一起使用,但可用于数组元素。 ·数字型输入字段可以配置两个或三个字段指示器,但是,仅有一个指示器作为检测字段的结果而置为ON,其它指示器仍为OFF。 ·如果同一个字段指示器分配给不同记录类型中的字段,它的状态(ON、OFF)是由所选择的最后一个记录类型决定。 ·对不同记录类型中的字段配置不同指示器时,指示器保持ON直到读入那个类型的另一个记录时为止。 同样,配置给一个记录类型内多个字段的字段指示器总是反映最后定义的字段状态。 ·同一个字段指示器可以在另一个输入规范表上规定作为字段指示器,作为结果指示器或作为一个记录标识指示器或作为记录关系指示器,但指示器的这种使用方法可能导致错误的结果,且不发出诊断信息。
·如果在所有三个位置上指定相同指示器,当选择有这个字段的记录时,该指示器总为ON。
1.4.1.5
结果指示器
结果指示器由计算规范表的71-76列上的内容定义。结果指示器的用途根据26-35列上指定的操作码来决定。例如,结果指示器可以用来检测算术操作以后的结果字段。标识记录没找到的条件,指出文件操作的异常/错误条件或指出文件结束的条件。 有效的结果指示器是: 01-99 OA-OG,OV LR KA-KN,KP-KY(仅和SETOF连用有效)。 H1-H9 L1-L9 U1-U8 RT
可以在计算规范表的三个地方(71-72列,73-74列,75-76列)指定结果指示器,在这些位置上的结果指示器确定检查的条件。
在大多数情况下,当执行一个计算时,结果指示器为OFF,如果结果指示器所指出的条件满足,指示器为ON,但是,对于这规则也有例外,见4.4.49的LOOKUP和4.4.81的SETON。结果指示器可以用在同一个计算行或其它计算或输出操作中作条件指示器用。当在同一行用它时,该指示器前面的设置决定是否执行该计算,如果执行,检查结果字段,决定指示器的当前设置。
1.4.1.5.1 配置结果指示器的规则
配置结果指示器时,记住下列事项: ·当结果字段引用整个数组时,不能使用结果指示器 ·如果检测多个操作的结果使用同一个指示器,最后一个操作决定该指示的状态 ·当L1-L9指示器作为结果指示器使用而且置为ON时,较低级指示器2,置为off。例如,如果L8为on,LY-L7不为on。 ·同一个指示器能用来检测某个操作的多个条件。 ·高H1-H9用做结果指示器并置为on时,程序暂停,除非在程序周期中检测该暂停指示器时它设置为off。
*...1....+....2....+....3....+....4....+....5....+....6....+....7... CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq.. C*
C* 用两个结果指示器来校验减法操作的不同条件。这些指示器给出工资名单 C* 作业计算执行的条件。如果HRSWKD大于40,指示器10设为ON,然后用 C* 它查找超时工资操作的所有条件。如果指示器20不是ON(雇员每周工作40 C* 小时或多于40小时),依每周40小时做常规计算。 C*
C HRSWKD SUB 40 OVERTM 3 01020 C*
C N20PAYRAT MULT (H) 40 PAY 6 2 C 10OVERTM MULT (H) OVRRAT OVRPAY 6 2 C 10OVRPAY ADD PAY PAY
C* 如果指示器20为ON (雇员每周工作少于40小四时),按每周少于40 C* 小时的方法计算工资。 C*
C 20PAYRAT MULT (H) HRSWKD PAY C*
图15 用结果指示器做计算条件
1.4.2 不在规范表中定义的指示器
并非所有的指示器都能在规范表格式上定义作条件指示器。外部指示器(U1-U8)是由CL命令定义或是由先前的RPG程序定义。内部指示器(1P,LR,MR和RT)是由程序周期本身定义的。
1.4.2.1
外部指示器
U1-U8均是外部指示器,这些指示器可以用CL程序或RPG程序设置。在CL程序中,它们是由CHGJOB命令或CRTJOBD命令的参数SWS(开关)来设置。在RPG程序中,它们可作为一个结果指示器或字段指示器设置。
外部指示器的状态可以在程序中通过把它们做为计算规范表上的结果指示器或在输入规范表上作为字段指示器来修改。但是,在程序执行期间用CL程序修改OS/400作业的开关状态不影响由RPGⅣ程序所使用的外部指示器拷贝,在程序中设置外部指示器ON或OFF不影响文件处理。当程序初始化时,文件处理功能和U1-U8指示器的状态有关,但,当程序用LR为ON正常结束时,外部指示器拷回到存储器,它们的状态反映了它们在RPGⅣ程序中最后的状态,因而外部指示器的当前状态可以为其它程序所用。
注:当RETRN和LR指示器是OFF一起使用时,可以指定一个非结束返回点,它不更新外部指示器。
1.4.2.2
内部指示器
内部指示器包括: ·第一页指示器 ·最后记录指示器 ·匹配字段指示器 ·返回指示器
1.4.2.2.1 第一页指示器(1P)
第一页指示器(1P)由RPGⅣ程序在程序开始运行时置为ON,并且在明细输出之后由程序置为OFF。在明细输出之后,处理第一个记录。1P指示器可以为在1P期间写出的标题或明细记录做条件限制,不要用1P指示器来限制用输入记录做数据的输出字段。因为此时输入数据还不能用。
1P不能用于总计或异常输出行,也不能与控制级指示器有AND关系使用。1P不能作为结果指示器。
1.4.2.2.2 最后记录指示器(LR)
在有主文件的程序中,在主文件/次文件中的最后一个记录处理后LR置为ON。它也可以由程序员置为ON。
LR 可以用来限制计算和在程序结束时执行输出操作。当LR置为ON时,所有其它的控制级指示器(L1-L9)也为ON。如果没有定义L1-L9中的任意一个指示器为控制级指示器,记录标识指示器,结果指示器或者由*INxx定义,这些指示器当LR为ON时,也都置为ON,但它们不能用在其它规范表中。
在没有主文件的子程序中,可以设置LR指示器作为ON作为结束程序的一种方法。要置LR为ON,你可以把LR指示器作为记录标识指示器或结果指示器。如果在明细计算期间LR指示器置ON。所有其它的控制级指示器在下一个周期开始时置为ON,在明细周期其余部分LR和记录标识指示器始终为ON,但是LR总计之前记录标识指示器为OFF。
1.4.2.2.3 匹配记录指示器(MR)
匹配记录指示器(MR)和匹配字段项M1-M9有关,它仅在有主文件和至少一个次文件中定义匹配字段的程序中使用。
当次文件记录中所有匹配字段和主文件记录中的所有匹配字段相匹配时,MR为ON。在文件和次文件记录的整个处理期间内都保持为ON,当所有总计计算总计输出及记录溢出处理好时,它为OFF。
在处理明细期间MR总是指出刚选择要处理的记录的匹配状态,在总计时,它反映以前记录的匹配状态,如果所有主文件记录和所有次文件记录相匹配,MR总是ON。
用MR指示器作为字段记录关系指示器或者在计算规范表,输入规范表内做条件指示器,指出仅在记录匹配时才做相应的操作。
有关匹配字段和多文件处理的详细信息请参看第6章“一般文件考虑”。
1.4.2.3
返回指示器(RT)
你可以使用RT指出控制返回到调用程序的内部的RPG逻辑,检查LR的状态之后,读下一个记录之前,决定RT是否为ON。如果RT是ON,控制返回给调用程序,当程序再次被调用时,置RT为OFF。
因篇幅问题不能全部显示,请点此查看更多更全内容