Chinaunix

标题: AS/400开发经验点滴(一) [打印本页]

作者: blogliou    时间: 2003-12-05 12:33
标题: AS/400开发经验点滴(一)
AS/400开发经验点滴(一)


AS/400系统开发工具及开发语言很多,有许多技术性的东西并不是我们能经常碰到的,但这些东西在一些实际应用中很有用处。本人在几年AS/400系统上的开发中,也有一些经验。有些东西如果不把其形成文字,过一段时间后,本人都会很快忘掉,比如我现在要写两年前的经验就很费劲。现把其中一些经验总结出来,与大家共享也行,自娱自乐也行。本文不是学术论文,仅仅是一些开发经验总结,有不严谨的地方必定在所难免。

一 如何在CL程序自动回复询问类消息(Inquiry Message)

在AS/400系统开发中,经常要与各种各样的消息打交道。有一类叫“Escape Message”的消息,是当程序出现错误后,会强迫程序异常结束,并告诉错误类型和原因。但经常时候我们不希望因为这些错误而使程序异常停止,在CL程序中,通常做法是用MONMSG命令来监视这些消息,而后采取相应的正确动作,或者引导程序结束。MONMSG一样还可以监视“Status Message”和“Notify Message”。

但是有一类“Inquiry Message”,MONMSG还是无法监视,这类消息通常有多个回复选择项,要求用户必须给一个选择答复,因而通常会暂停程序运行,而显示一个要求用户给消息进行回复的画面。那么如何在程序中让程序自动选择一个正确的回复项回复呢?如能自动答复,就不需要手工再回复了。

在作业JOBD里,有INQMSGRPY选择项,有三个选择:*RQD,*DFT,*SYSRPYL,这个INQMSGRPY就是表示指定Inquiry Message的答复方式,通常创建JOBD的时候INQMSGRPY项缺省是*RQD,这就表示需要操作员手工答复方式。而*DFT和*SYSRPYL就表示了两种程序可以自动答复的方式。

1.        消息答复缺省值法

如果在作业JOBD里INQMSGRPY选项指定为*DFT方式,则程序会自动使用消息的缺省答复项,询问消息就不会再在屏幕上显示。消息的缺省答复项,可以用CHGMSGD命令事先手工改好,也可以在程序中加入。比如下面的命令可以先在程序中设定:

CHGMSGD    MSGID(CPA3E01) MSGF(QCPFMSG) DFT(G)

此语句表示修改QCPFMSG消息文件中的CPA3E01消息的缺省答复为’G’(表示继续执行)。

2.        系统答复列表法

如果在作业JOBD里INQMSGRPY选项指定为*SYSRPYL方式,则程序会自动使用系统答复列表中定义的答复项。AS/400系统有一系统答复列表(System Reply List)。System Reply List允许用户指定某已定义在列表中消息的答复方式。System Reply List包含有序号、消息表示符、答复值、选择比较数据等。可以用WRKRPYLE命令查看System Reply List的所有内容。下面就是用WRKRPYLE命令查看到的内容:

  1. 2=Change   4=Delete

  2.      Sequence  Message                                             
  3. Opt   Number  ID                        Reply                Compare Value   
  4. -        10        CPA0700        D                        *NONE            
  5. -        20        RPG0000        D                        *NONE            
  6. -        30        CBE0000        D                        *NONE            
  7. -        40        PLI0000        D                        *NONE            
  8. -        50        CPF7025        I                        *NONE            
  9. -        60        CPA3E01        G                        *NONE            
  10. -       1111        CPA3708        G                        *NONE            
复制代码

可以用ADDRPYLE命令把你自己要定义的消息及缺省答复值加入。注意加入的时候Sequence Number项不能跟System Reply List已存在的重复。

但是用系统答复列表法有个缺陷,那就是把ADDRPYLE命令加入到程序中不方便,因为System Reply List里的Sequence Number要求唯一,所以不能重复加入。而且当程序移到不同机器运行时,还必须把消息缺省答复重新加入 System Reply List。

除了在JOBD可以指定消息答复方式外,还可以用BCHJOB和SBMJOB提交作业时在INQMSGRPY选择项里指定消息回复类别。BCHJOB和SBMJOB命令将会覆盖JOBD的答复方式。如果使用缺省答复方式和SBMJOB命令结合,可以先编一CL程序,就可以做到自动回复与机器和JOBD无关性,例子如下:

  1. CHGMSGD   MSGID(CPA3E01)  MSGF(QCPFMSG)  DFT(G)
  2. SBMJOB     CMD(CALL PGM(SMCRTRDBCL))  JOB(SMCRTRDBCL)   +
  3. INQMSGRPY(*DFT)
复制代码

作者: yoyoage    时间: 2003-12-05 12:59
标题: AS/400开发经验点滴(一)
嗯,挺不错,对我是新知识哦
作者: xuguopeng    时间: 2003-12-05 13:01
标题: AS/400开发经验点滴(一)
不错不错 ,加油~~ 等着你继续呢
作者: dfangyang    时间: 2003-12-05 15:27
标题: AS/400开发经验点滴(一)
不错,continue
作者: blogliou    时间: 2003-12-05 17:58
标题: AS/400开发经验点滴(一)
二 如何在RPG程序使用BLOCK关键词提高读写文件速度

RPG编程通常要与物理文件、逻辑文件等各类文件打交道。在RPG的F定义行里有一BLOCK关键词,善加使用这一关键词可以大幅度提高文件的读写速度。这在对具有大量数据的文件进行批处理时,效果特别明显。使用方法如下:

1.        定义RPG程序F行(文件描述规范):

文件描述规范里有一BLOCK(*YES|*NO)关键词。它控制着文件的块读写方式。该关键词只对DISK或SEQ类型的文件有效。我们常见的物理文件(PF)或逻辑文件(LF)就是DISK文件。

在缺省情况下,即F行关键词位置没有定义BLOCK时,在编译RPG程序时,对于输入记录,BLOCK缺省值为*NO,即文件不会以块的方式读入;对于输出记录,BLOCK缺省直为*YES。但上面编译缺省值需要先符合下面条件:

(1)        文件是程序描述文件(program-described)。
(2)        文件如果是外部描述文件(externally-described),则文件应只有一个记录格式(Record Format)。
(3)        在文件规范描述里(F行),不能使用RECNO关键词。

如果要使文件输入记录以块方式(BLOCK)读入,则F行必须指定BLOCK关键词,并赋值为*YES, 比如,下面定义了一外部描述的DISK类型的文件,其读入方式采用BLOCK方式:

  1. FJRNRBUFP  IF   E             DISK    BLOCK(*YES)   
复制代码



2.使用CL程序调用,并用OVRDBF覆盖文件属性

光是在RPG的文件描述里定义BLOCK(*YES),并不能使程序按BLOCK方式工作。需要先使用OVRDBF命令改变一下文件的属性。OVRDBF是个不错的命令,它不仅可以在程序内部改变文件名称,还可以在不改变文件名称的情况下,改变文件的一些属性参数,或者同时改变文件名称及文件属性参数。要使BLOCK方式正常工作,就需要先用OVRDBF命令改变文件的属性。要使BLOCK正常工作,需要指定SEQONLY(*YES)属性,即文件是按顺序读,RPG程序中不能有随机读写函数,比如READE等。SEQONLY(*YES)允许把多个记录放进内部数据管理缓冲区(Internal data management buffer),然后在一个时间点一次性把这些记录传给RPG程序。

在指定文件为SEQONLY(*YES)属性的同时,还应指定一次读取到内部缓冲区最大记录数,该记录数与缓冲区和记录的大小有关,缓冲区越大,记录长度越小,能够一次读取的最大记录数越多。系统缺省最大记录数为4,实际工作中可以通过反复测试来验证系统能够一次读取的最大记录数,当设定的最大记录数*记录长度>;内部缓冲区后,程序会报一错误。OVRDBF修改文件属性示范例子如下:

  1. OVRDBF     FILE(JRNRBUFP)  SEQONLY(*YES  34)
复制代码


上面语句规定了RPG程序可以对JRNRBUFP文件进行顺序BLOCK读写,一次可以读取34条记录进内部缓冲区。

注意事项:
(1)        要使用BLOCK方式,必须先用CL命令OVRDBF定义文件属性,然后调用RPG程序,不可以在RPG程序内部调用OVRDBF 。
(2)        使用BLOCK方式,要求文件为顺序读写方式,所以RPG程序中不能使用READE等随机读写函数
(3)        通常对大文件进行批处理时,文件都是顺序读写的,这时候使用BLOCK方式,效果特别明显,实际经验发现速度可以提高5-10倍。
作者: blogliou    时间: 2003-12-05 17:58
标题: AS/400开发经验点滴(一)
三 如何在RPG程序里捕捉与文件操作有关的系统消息

AS/400系统里有大量各类消息,应用程序经常会因为意外情况被这些消息所打断,应用程序或者弹出消息窗口,或者在作业状态中报MSGW,等待人工干预。在CL程序里可以使用MONMSG命令来捕捉消息或自动答复消息机制来处理各样的消息,使程序始终能够正确地运行。但在RPG程序里,又怎么捕捉消息然后对消息进行特别处理呢?

RPG程序实际主要是对各类各样的文件操作,比如DISK文件(物理文件、逻辑文件)、显示文件、通信文件、打印文件等等。下面以DISK文件为例示范如何在RPG程序里捕捉错误消息。

1.        在文件描述规范(F行)里定义INFDS关键词

在RPG文件描述规范的关键词里,有一INFDS关键词。这个关键词是用来定义文件信息数据结构的,这个结构对每个文件都是唯一的。里面包含有几种Feedback Information。其中从1-80位是File Feedback Information, 在File Feedback Information的第46-52位定义了Message ID,当对文件操作出现错误消息时,这个错误消息就会保存在这个位置。在数据规范定义(D行)里把INFDS结构里的46-52位定义一变量,这样我们就可以获得错误消息了。下面是F行和D行的示范例子

  1. FTESTMSG     O    F 3750        DISK    USROPN         
  2. F                                          INFDS(MSGFD)   

  3. D MSGFD              DS                        
  4. D  MSGID                 46     52   
复制代码

      
2.        在文件描述规范里定义INFSR(*PSSR)关键词

实际上如上义后,我们仍然不能捕捉系统错误消息,因为文件出现错误消息后,就会发生以外退出了。在文件规范描述里还有一个INFSR关键词,这个关键词里指定一个子例程,来接收文件意外错误后的控制。这个子例程的名字可以是*PSSR。通常我们是指定这个子例程来对异常错误进行相同的处理。但是如果我们与上面定义的文件信息结构的中MSGID相结合,我们就可以对单独的信息进行特别的处理了,从而实现了对系统消息的捕捉与特别处理。下面是F行改正后例子:

  1. FTESTMSG     O    F 3750        DISK    USROPN         
  2. F                                          INFDS(MSGFD)   
  3. F                                          INFSR(*PSSR)

  4. D MSGFD              DS                        
  5. D  MSGID                 46     52   
复制代码


下面是接收错误消息控制的子例程的例子:

  1. C     *PSSR         BEGSR                                    
  2. C     MSGID        IFEQ      'CPF5006'                       
  3. C                   。。。。。            
  4. C                   GOTO      XXXTAG                       
  5. C                   ENDIF                                    
  6. C                   。。。。
  7. **
  8. C                   MOVE      '*DETC '      RETURN  
  9. **                 (Continue at the beginning)
  10. C                   ENDSR     RETURN
复制代码

作者: mamei    时间: 2003-12-05 18:29
标题: AS/400开发经验点滴(一)
精华!
作者: qingzhou    时间: 2003-12-05 18:32
标题: AS/400开发经验点滴(一)
不错,不错!
让我们也共同分享你的成功!
作者: layyf    时间: 2003-12-05 18:44
标题: AS/400开发经验点滴(一)
thank you
作者: dashuai    时间: 2003-12-08 20:45
标题: AS/400开发经验点滴(一)
收藏,期待下篇。
作者: 偷偷的学    时间: 2003-12-11 20:19
标题: AS/400开发经验点滴(一)

宝哥,看了你的这几篇贴子真是受益匪浅。

以前在农联社的时候就向你偷师不少,佩服佩服。

以后会多多向你请教
作者: hanyu    时间: 2003-12-12 08:41
标题: AS/400开发经验点滴(一)
谢谢
作者: andrewleading_h    时间: 2004-01-05 17:26
提示: 作者被禁止或删除 内容自动屏蔽
作者: fairyboy    时间: 2004-12-01 08:03
标题: AS/400开发经验点滴(一)
晕死了,这么好的东西,我怎么到今天才看到呢?
偶像啊,加油楼主
作者: Red_Crow    时间: 2004-12-01 08:52
标题: AS/400开发经验点滴(一)
支持!
作者: thursday    时间: 2004-12-01 09:32
标题: AS/400开发经验点滴(一)
收藏,帮顶!
作者: hxfang2000    时间: 2007-03-23 21:45
太厉害了,非常感谢!!先收藏了。。
作者: 桃子0330    时间: 2007-03-24 19:55
学习,学习
作者: yzclxw    时间: 2007-03-28 11:52
hao
作者: magic_007    时间: 2007-03-29 11:53
继续收藏
作者: nn531    时间: 2007-04-02 13:24
大哥,又没有COBOL方面的。
哪位可以提供COBOL的培训信息,多谢(wang02163696@yahoo.com.cn)
作者: pmf    时间: 2007-07-09 11:50
学习了,收藏,谢谢啊
作者: evoqsongsong    时间: 2007-08-02 16:16
3Q,太好了
作者: wgp198313    时间: 2007-08-02 18:19
刚学400 非常有收藏价值,谢谢!
作者: wangyang6614    时间: 2007-08-13 10:45
好东西,谢谢分享!
作者: guilao    时间: 2008-03-19 23:33
谢谢你的经验分享。。。lz
作者: loveeyes007    时间: 2008-03-26 14:23
很好,值得收藏!!
作者: 广水山    时间: 2009-05-19 15:04
标题: 回复 #5 blogliou 的帖子
"在指定文件为SEQONLY(*YES)属性的同时,还应指定一次读取到内部缓冲区最大记录数,该记录数与缓冲区和记录的大小有关,缓冲区越大,记录长度越小,能够一次读取的最大记录数越多。系统缺省最大记录数为4,实际工作中可以通过反复测试来验证系统能够一次读取的最大记录数"

补充一下,一次读取的记录数是可以计算出来的,而不需要反复测试。由于AS400一次IO的缓冲是4K,所以,一次读取的记录数=4k/文件的记录的长度。比如文件的RECORD LENGTH是1K,那一次读取的记录数就是4。如果是512,那一次读取的记录数就是8。。。
作者: KouKa400    时间: 2009-05-19 20:40
要顶
作者: wzjwqs    时间: 2013-11-22 17:19
感谢分享!!!
作者: luear    时间: 2013-12-27 16:57
嗯,挺不错,对我是新知识哦


   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2