RPG PL/1←→ RPG対応
次ページ 目次



PL/1(ピー・エル・ワン)のサポートが中止になりました。
PL/1を使用していた方たちにとって、新言語への乗換はかなりな負担と思われます。
ここでは、多少なりとも手助けとなるよう、PL/1と基本思想が比較的似ている、
RPG-IV(ILE−RPG)と対比させてPL/1を紹介します。
RPG-IVはここでは単にRPGと呼ぶことにします。


一般形


PL/1

PL/Iのプログラムはメイン・プロシージャーとサブ・プロシージャーからなります。
サブ・プロシージャーはメイン・プロシージャーに含まれる場合と、サブ・プロシージャー
だけで、独立して存在する場合とがあります。
また、サブ・プロシージャーの中に更にサブ・プロシージャーを包含することもできます。(汎用機の場合)
メイン/サブとも、PROCEDURE(省略形PROC)で始まり、それと対になるENDで終了します。
メイン・プロシージャーの始まりのPROCEDUREの命令には,OPTIONS(MAIN)
のパラメータをつけます。


RPG

RPGはメイン・プロシージャー、サブ・プロシージャー、サブ・プログラムからなります。
プロシージャーはメイン/サブの2階層のみです。
メイン/サブそれぞれのプロシージャーはサブ・プログラムを包含できます。
サブ・プログラムは演算仕様書のBEGSRで始まり、同じくENDSRで終わります。
メイン・プロシージャーは制御仕様書(仕様書コード:H)で始まります。
サブ・プロシージャーは24桁目にBを指定したプロシージャー仕様書で始まり、同じくEを
指定したプロシージャー仕様書で終わります。

例ー1:比較的単純なPL/1プログラム

PGM111     : PROC OPTIONS(MAIN) ;                       
      DCL 1  WORK,                                      
             2   YMD1     PIC  '999999' ,               
             2   YMD1A    PIC  '99999999';              
      YMD1   = 991212 ;                                 
      CALL  Y2K  (YMD1, YMD1A);                         
      RETURN ;                                          
/*- SUB PROC ------------------------------- */         
Y2K : PROC (YMD2, YMD2A) ;                              
                                                        
      DCL    YMD2     PIC  '999999' ,                   
      DCL    YMD2A    PIC  '99999999' ;                 
      IF  YMD2    >   900000   THEN                     
            YMD2A    =  YMD2     + 19000000 ;           
      ELSE                                              
            YMD2A    =  YMD2     + 20000000 ;           
      END ;                                             
      END ;                                             
      END ;                 

このプログラムはメイン・プロシージャーから、サブ・プロシージャーY2Kを呼出しています。
データの受渡しはパラメータで受け渡しています。対応するRPGを示します。

例:対応するRPG

H DATEDIT(*YMD-)                                                     
D*------------------------------------                               
D* プロトタイプの指定                                                
D* 呼び出されるプログラムは 6S0 8S0 のパラメータを要求               
D SUBY2K          PR                                                 
D                                6S 0                                
D                                8S 0                                
D*------------------------------------                               
D  YMD1           S              6S 0                                
D  YMD1A          S              8S 0                                
C*------------------------------------                               
C     *ENTRY        PLIST                                            
C                   PARM                    YMD1                     
C                   CALLP     SUBY2K (YMD1:YMD1A)                    
C     YMD1A         DSPLY                                            
C                   SETON                                        LR  
C                   RETURN                                           
** ここからサブ・プロシージャー                                        
**               ↓サブ・プロシージャーの始まり
P SUBY2K          B                                                    
D SUBY2K          PI                                                   
D  YMD2                          6S 0                                  
D  YMD2A                         8S 0                                  
C*------------------------------------                                 
C     YMD2          IFGT      700000                                   
C                   EVAL      YMD2A = YMD2+ 19000000                   
C                   ELSE                                               
C                   EVAL      YMD2A = YMD2+ 20000000                   
C                   ENDIF                                              
C                   EVAL      YMD1  = YMD1                             
C                   RETURN                                             
P                 E                                                    
*                ↑サブ・プロシージャーの終わり

ファイル定義


PL/1

PL/1ではファイルの定義はDECLARE(省略形はDCL、以下DCLとします)命令で行ないます。
一般形は次のとおりです。

DCL     FILE名    属性リスト;

属性リストは、ブランクで区切ったファイルの属性を並べたもので、その順序は任意です。
ファイルの属性には次のようなものがあります。

属性 意味
FILE データタイプがファイルである
RECORD/STREAM レコード型入出力をするか、ストリーム型入出力をするか。
INPUT/OUTPUT/UPDATE 入力ファイルか、出力ファイルか、入出力ファイルか
PRINT 印刷属性
SEQUENTIAL/DIRECT 順次アクセスファイルか、直接アクセスファイルか
KEYED キー利用アクセスかそうでないか。
ENVIRONMENT 外部依存属性
     INTERACTIVE 会話型装置ファイル
     INDEXED インデックスあり
     DESCRIBED 外部記述情報使用

DCLは非実行命令です。実行命令より後にあっても差し支えありません。

RPG

RPGではファイルの定義はファイル仕様書で行います。ファイル仕様書の順序は、制御仕様書
の後です。ファイル仕様書を記述できるのはメイン・プロシージャーのみです。
以下に例を示します。

例:印刷出力ファイル

PL/1
	DCL  QPRINT  FILE STREAM OUTPUT PRINT; 
RPG
      ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 
      FQPRINT    O    F  132        PRINTER OFLIND(*INOV) 
厳密な意味での対応ではありません。

例:画面ファイル
PL/1
    DCL  RM420S  FILE RECORD SEQUENTIAL UPDATE ENV(INTERACTIVE); 
RPG
    ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 
      FM420L02   IF   E           K DISK 


例:順次よみするキー付きファイル
PL/1
    DCL  M420L02  FILE RECORD SEQUENTIAL KEYED  INPUT  
                                   ENV(INDEXED DESCRIBED);
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 
     FM420L02   IF   E           K DISK 


例:直接読取するデータベースファイル

PL/1
	DCL  M420  FILE RECORD DIRECT KEYED UPDATE  ENV(INDEXED DESCRIBED); 

RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
     FM420      UF A E           K DISK 


配列、データ構造、変数名の定義


PL/1

PL/1ではDCL命令で行います。
一般形は次のとおりです。

DCL 変数名 属性リスト [,変数名 属性リスト[,・・・]];
属性 意味
CHARACTER/PICTURE/BIT 文字列、10進数、ピクチャー属性、ビット列
FIXDE/FLOAT 固定小数点データ/浮動小数点データ
DECIMAL/BINARY 10進数/2進数
BASED 基点アドレス属性
STATIC/AUTOMATIC 静的/自動アロケーション属性
INITITIAL 初期値属性

PL/1でデータ構造を定義するときは、名称の前にそのレベル番号をつけます。
配列を定義するときは、変数名の後ろに、( )にいれた次元属性、要素数を記述します。
初期値は、INITキーワードパラメータで、( )内に初期値のリストとして与えます。

例:

工事中

RPG

RPGでは定義仕様書で定義のタイプを指定して定義します。
データ構造の場合は,定義のタイプを’DS’とします。
配列の場合は、定義のタイプを’S’とし、キーワードパラメータDIMで要素数とともに指定
します。

初期値

初期値はキーワードパラメータINZで与えます。


例:PL/1 INITパラメータによる初期値
         DCL 1 FLD444,                                                   
             2   FLD02    CHAR      (12)  INIT('111111111122'),        
             2   FLD03    CHAR      (52)  INIT(                        
           ' ABCDEFGHIJKLMNOPQRSTUVWXYZ1234 '); 

例:RPG INZパラメータによる初期値
     DFLD444           DS                                          
     D FLD02                     000012    INZ('111111111122')               
     D FLD03                     000052    INZ(' ABCDEFGHIJKLMN -  
     D                                      OPQRSTUVWXYZ1234 ')  


配列に複数の初期値をあたえるときは、キーワードパラメータCTDATAを指定し、コンパイル時配列とします。
このとき、1レコードあたりのデータ件数もPERRCDパラメータであたえます。

例:PL/1配列に複数の初期値
         DCL FFFF(20)          CHAR(8) STATIC INIT(                    
                'AAA02-01','AAA02-02','AAA02-03','AAA02-04','AAA02-05',
                'AAA03-01','AAA03-02','AAA03-03','AAA03-04','AAA03-05',
                'AAA04-01','AAA04-02','AAA04-03','AAA04-04','AAA04-05',
                'AAA05-01','AAA05-02','AAA05-03','AAA05-04','AAA05-05' 
               );          

例:RPG,コンパイル時配列による初期値
RPGプログラムの末尾

	プログラム途中省略

     C                   ENDDO                      
** FFFF                                             
AAA02-01                                            
AAA02-02                                            
AAA02-03                                            
AAA02-04                                            
AAA02-05                                            
AAA03-01                                            
AAA03-02                                            
AAA03-03                                            
AAA03-04                                            
AAA03-05                                            
AAA04-01                                            
AAA04-02                                            
AAA04-03                                            
AAA04-04                                            
AAA04-05                                            
AAA05-01                                            
AAA05-02                                            
AAA05-03                                            
AAA05-04 
AAA05-05 



サブ・プロシージャー内での定義と有効範囲


PL/1
DCLで定義します。定義した項目の有効範囲は、そのプロシージャーとその内側のプロシージャーのみです。

RPG
定義仕様書で定義します。定義した項目の範囲は、そのプロシージャーとその内側のプロシージャーのみです。
サブ・プロシージャー何も指定しないと属性はPL/1でのAUTOMATIC相当の属性になります。


構造名、変数名の桁数



構造名、変数名の桁数はPL/1は最大31桁です。RPGは14桁です。


演算命令


PL/1

プロシージャーの内部に実行順を考慮して記述します。
PL/1は自由形式で一般形は、

ラベル: 命令  定置パラメータ  キーワードパラメータ [キーワードパラメータ] ;

の形です。

ラベルと命令は:(コロン)で区切ります。ラベルは省略できます。
命令文の終わりは;(セミコロン)で終わります。
1行に複数の命令文を記述することもできます。

例:
  STEP10 : READ  FILE(FILE10)  INTO(FILE10R) ;   


RPG

演算仕様書(仕様書コード:C)に実行順、実行条件などを考慮して記述します。
RPG-IIIからの様式を引き継ぐ場合は、固定カラム様式ですが、EVALなど拡張様式を
使用する場合は、拡張様式(EXTENDED-FACTOR2)の部分)は自由形式です。

     CL0N01FACTOR1+++++++OPCODE&EXTEXTENDED-FACTOR2+++++++++++++++++++++++++ 
     C                   EVAL      XXXX    = ( AAA + BBB )                   
     C                                     / ( CCC - DDD )                   


各種演算命令


割付

PL/1

変数名 = 式 ;の形はRPGでは、 EVAL  変数名  =  式 が対応します。
記述様式は拡張様式です。

例:
PL/1
             XXX   =  DAY  - YY * 10000 - MM * 100 ; 
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+
     C                   EVAL      XXX = DAY  - YY * 10000 - MM * 100 
     C*     トークンの途中でなければ、継続は自由です。
     C                   EVAL      XXX 
     C                             = DAY - YY * 10000 
     C                             - MM * 100

条件による実行制御


IF

IF命令はRPGではIF,ELSE,ENDIFの複数の命令を組み合わせて実現します。
例:
PL/1
       IF   ABIT = 1  THEN  WDUP = WDUP + 1 ;          
                      ELSE  WDUP = WDUP - 1 ;             
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 .
     C                   IF        ABIT = 1                                         
     C                   EVAL      WDUP = WDUP + 1                  
     C                   ELSE
     C                   EVAL      WDUP = WDUP - 1
     C                   ENDIF                                          


ケースによる複数条件分岐

複数条件による分岐はSELECT,WHENxx,OTHER,ENDSLの複数の命令を組み合わせて実現します。
例:
PL/1
           SELECT (KUBUN) ;                 
             WHEN ('10') GOTO  LBL10;        
             WHEN ('20') MSG1='BBBBBBBB' ;       
             WHEN ('30') MSG1='CCCCCCCC' ;    
             OTHERWISE   MSG1='        ' ;
           END ;               
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+.
     C                   SELECT                                             
     C     KUBUN         WHENEQ    '10'                                     
     C                   GOTO      LBL10                                    
     C     KUBUN         WHENEQ    '20'                                     
     C                   EVAL      MSG1 = 'BBBBBBBB'                        
     C     KUBUN         WHENEQ    '30'                                     
     C                   EVAL      MSG1 = 'CCCCCCCC'                        
     C                   OTHER                                              
     C                   EVAL      MSG1 = *BLANK                            
     C                   ENDSL                                              

繰返し処理の制御



DO 増分指定の繰返し

増分指定の繰返しは、RPGでは項目1に初期値、項目2の終了値、結果のフィールドに変数を与えます。
例:
PL/1
      DO  X = 1 TO 10 ;
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 
     C     1             DO    10            X                         


DO 数値リストの繰返し

DO X = 3,1,4,1,5,9,2 の形式の値を任意に変えての繰返しは
RPGには該当機能はありません。


DO UNTIL( 式 )

UNTIL型の繰返しはRPGではDOU命令が対応します。繰返しの条件式は拡張様式の項目2に記述します。
例:
PL/1
       DO  UNTIL(AA=BB | CC<>DD) ; CC = DD ; END;   
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 
     C                   DOU       AA=BB OR CC<>DD                     
     C                   EVAL      CC=DD                               
     C                   ENDDO                                         


DO WHILE(式)

WHILE型のの繰返しは、RPGではDOW命令が対応します。繰返しの条件式は拡張様式の項目2に記述します。

PL/1
       DO  WHILE((A=B) | SUBSTR(AA,BB,CC) = 'DDD') ; 
           C = D ;                                   
       END ;                                         
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 .
     C                   DOW       (A=B) OR %SUBST(AA:BB:CC) = 'DDD'      
     C                   EVAL      C=D                                    
     C                   ENDDO                                            


入出力命令


PL/1の入出力はストリーム型レコード型があります。
ストリーム型は、プログラムからみたとき、データを一連の紐のような感じで入出力するもので
たとえ1レコードが80バイトであったとしても、レコード長さに関係なく、40バイト、30
バイト、50バイトのように入出力するものです。
一方、レコード型は、1回の入出力命令で1レコード分だけプログラムに読取りあるいは書出しします。


ストリーム入出力

入力はGET,出力はPUTという命令ですが、RPGには対応する命令も機能もありません。

レコード入出力

順次、直接、画面との入出力にわけられます。

順次入出力

順次入出力をするには、ファイルはSEQUENTIALの属性であることが必要です。(DCL参照)
一般形は次のとおりです。[  ]は省略可能を意味します。

READ  FILE(ファイル名)  INTO(レコード名) [KEYTO(キーフィールド名)]
WRITE FILE(ファイル名) FROM(レコード名) [KEYFROM(キーフィールド名)]

RPGではREAD/WRITE(あるいはEXCPT)命令が対応します。

例:順次読み取りの例
PL/1
           READ  FILE(M420)  INTO(M420R) ;
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+. 
     C     P@SLNO        READ      M420R                                  99 


直接入出力

直接入出力をするには、ファイルはDIRECT属性であることが必要です。(DCL参照)
一般形は次のとおりです。[  ]は省略可能を意味します。

READ  FILE(ファイル名)  INTO(レコード名) KEY(キーフィールド名)
REWRITE FILE(ファイル名) FROM(レコード名) [KEY(キーフィールド名)]

RPGではCHAIN/UPDATEが対応します。

PL/1
      READ  FILE(M420)  INTO(M420R)  KEY(S1TKNO)
RPG
     ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+. 
     C     S1TKNO        CHAIN     M420R                              99     


画面への入出力

PL/1ではWRITE命令とREAD命令で行いますが、RPGでは両方の機能を持った
EXFMT命令があります。

例:PL/1
          WRITE FILE(FILE111) FROM(FLD111) OPTIONS(RECORD('PANEL01')    
                                           INDICATORS(IND111));  
          READ  FILE(FILE111) INTO(FLD111) OPTIONS(RECORD('PANEL01')    
                                           INDICATORS(IND111));  

例:RPG
                C                   EXFMT     PANEL01                    


例外処理


PL/1での例外処理はON命令により、例外条件が発生したときの処理を記述します。
処理は1命令だけのこともあり、BEGINブロックを構築して複数の命令を実行させることもできます。
ON命令は実行命令です。DCLのような非実行命令ではありません。
RPGではこの機能に対応する命令はありません。

例:
ON ENDFILE(M420) GO TO LAST;

この例では、ENDFILE条件が発生したとき、LASTへ実行を移すよう指定して
います。

ON ENDFILE(M420) BEGIN ;
    MSG1 = 'BUTSU BUTSU' ;
    MSG2 = 'GUCHI GUCHI' ;
    GO TO YAMETA;
END ;
この例では、ENDFILE条件が発生したとき、MSG1とMSG2に値をセットしてYAMETAへ
実行を移すようにしています。


RPGではこれらの処理を完全に代替することはできないので、実行結果の標識で処理するか
%ERRORのような関数を使用して代用処理することが必要です。





次ページ 目次



(C)COPYRIGHT ISHIOKA KATSUHIDE ,2000