ILE で RPG サイクル (フリー・フォーマット/サブプロシージャの使用)

RPG IV になって、フリー・フォーマットになったり、サブプロシージャのようなものが使えるようになったり、ILE になって C の関数や Java のメソッドが相互乗り入れ的に自由に使えるようになったり、といろんな新しい機能が増えていますが、それで過去のものがなくなってしまっているわけではありません。

RPG のもともとの機能に"RPG サイクル"といわれるものがありますが、これなどは、単純にテーブルを読んでリスティングを行う、といった処理にはとても便利な機能です。

たとえば、一次ファイルを全件読んで、二次ファイルとマッチングを行いつつ処理をし、その結果をスプールに書く、といったような場合、とても簡単にプログラムを作ってしまうことができるわけです。

今回はこのサイクルという機能を簡単に紹介してみたいと思います。


今回の例は「ILE RPG プログラマーの手引き」の第一章「RPG IV プログラミング言語の概要」の 7ページからに載っている「ILE RPG プログラムの例」をちょっと修正したものでです。

処理対象のファイル

以下のような二つのファイル (テーブル) があるとしましょう。

EMPLOYEE

     A          R EMP_REC                                                       
     A            EMP_NUMBER     5          TEXT('EMPLOYEE NUMBER')             
     A            EMP_NAME      16          TEXT('EMPLOYEE NAME')               
     A            EMP_RATE       5  2       TEXT('EMPLOYEE RATE')               
     A          K EMP_NUMBER

TRANSACT

     A          R TRN_REC                                                       
     A            TRN_NUMBER     5          TEXT('EMPLOYEE NUMBER')             
     A            TRN_HOURS      4  1       TEXT('HOURS WORKED')                
     A            TRN_BONUS      6  2       TEXT('BONUS')

要件とメインの処理

こんな処理を考えて見ましょう。

従業員の勤務状況テーブル (TRANSACT) を従業員テーブル (EMPLOYEE) とつきあわせて全件処理し、一致したものについては給与計算を行って結果を出力する。一致しなかったものについてはその旨の警告メッセージをかわりに出力する。

この場合、いわゆるプログラムとしての処理は以下の部分だけでOK です。これだけですよ!!

      /free                                                                                         
         chain trn_number emp_rec;                                                                  
         if %found(EMPLOYEE);                                                                       
           pay = CalcPay (emp_rate: trn_hours: trn_bonus);                                          
         endif;                                                                                     
      /end-free

メインの処理以外に必要な定義

その他の定義も見ていきましょう。

一次ファイルと定義したものは、SQL のテーブル・スキャンと同様に全件読みます。そこは F 仕様書と言われる部分で、指定位置に P と書くだけでそうなります。

     FTRANSACT  IP   E           K DISK

マッチングを書けるファイルを定義します。

     FEMPLOYEE  IF   E           K DISK

chain 命令で、一次ファイルの中の trn_number というフィールド(カラム) を使って二次ファイルのキーをマッチングさせます。SQL で言えばネステッド・ループ・ジョインを実行しているわけです。

         chain trn_number emp_rec;

キーがヒットした場合は印刷を制御するために定義した 99 という標識をオンにします。

     Iemp_rec       99

キーがヒットした場合に、必要な計算を行います。アプリケーションの処理になりますね。ここでは後での再利用を考えて、CalcPay というひとまとまりの手続き (プロシージャ) にしておき、それを呼び出すようにしてあります。

         if %found(EMPLOYEE);                                                                       
           pay = CalcPay (emp_rate: trn_hours: trn_bonus);                                          
         endif;

印刷用の定義を行うところで (O 仕様書) で、99 がオン (キーがヒットした場合) の場合には明細を出力、99 がオフの時 (キーがヒットしなかった場合) は "NOT ON EMPLOYEE FILE" というメッセージを出力するように制御を行っています。

     O          D   N1P 99               2                                                          
     O                       TRN_NUMBER           5                                                 
     O                       EMP_NAME            24                                                 
     O                       EMP_RATE      L     33                                                 
     O                       TRN_HOURS     L     40                                                 
     O                       TRN_BONUS     L     49                                                 
     O                       Pay                 60 '$     0.  '                                    
     O          D   N1PN99               2                                                          
     O                       TRN_NUMBER           5                                                 
     O                                           35 '** NOT ON EMPLOYEE FILE **'

CalcPay という手続きは Rate、Hours、Bonus という三つのパラメータ (引数) をとるように定義されています。

     D CalcPay         PR             8P 2                                                          
     D   Rate                         5P 2 VALUE                                                    
     D   Hours                       10U 0 VALUE                                                    
     D   Bonus                        5P 2 VALUE

実際の処理の内容は、このプログラムの場合は以下のように下にまとめて記述されています。いろんなプログラマーに使ってもらえるように独立した別の共用プログラムの中に記述されていてもいいわけです。
また、この手続きの中でのみ有効な Overtime という変数を定義しています。この Overtime というフィールドはメインの処理からは隠蔽されていて見えません。これをローカル変数といいます。

     P CalcPay         B                                                                            
     D CalcPay         PI             8P 2                                                          
     D   Rate                         5P 2 VALUE                                                    
     D   Hours                       10U 0 VALUE                                                    
     D   Bonus                        5P 2 VALUE                                                    
     D  OverTime       S              5P 2 INZ(0)                                                   
      *                                                                                             
      /free                                                                                         
          if Hours > 40;                                                                            
            OverTime = (Hours - 40) * Rate * 1.5;                                                   
            Hours = 40;                                                                             
          endif;                                                                                    
          return  Rate * Hours + Bonus + Overtime;                                                  
      /end-free                                                                                     
      *                                                                                             
     P CalcPay         E

出力仕様書の中で、1ページ目のみに印刷するものを定義しています。

     OQSYSPRT   H    1P                  2  3                                                       
     O                                           35 'PAYROLL REGISTER'                              
     O                       *DATE         Y     60                                                 
     O          H    1P                  2                                                          
     O                                           60 Heading1                                        
     O          H    1P                  2                                                          
     O                                           60 Heading2

また、プログラムの終わりに印刷するものも定義しています。この "LR" という文字を見て、なぜ RPG の最後におまじないのように *inLR = *on としなくてはならないか、と理解できるかもしれませんね?!

     O          T    LR                  2                                                          
     O                                           33 'END OF LISTING'

プログラム全文

全部まとめたものが↓になります。これで計算処理から出力まで全部できるわけですね。

     H DATEDIT(*YMD/) DFTACTGRP(*NO)                                                                
      *                                                                                             
      * 読み込みファイルの定義                                                                                 
     FTRANSACT  IP   E           K DISK                                                             
     FEMPLOYEE  IF   E           K DISK                                                             
      *                                                                                             
      * 出力ファイルの定義                                                                                   
     FQSYSPRT   O    F   80        PRINTER                                                          
      * 出力フィールド(ヘッダー)の定義                                
     D Heading1        C                   'NUMBER  NAME              RATE    H-                    
     D                                     OURS  BONUS    PAY       '                               
     D Heading2        C                   '______  ________________  ______  _-                    
     D                                     ____  _______  __________'                               
      * サブプロシージャの定義                                                                                 
     D CalcPay         PR             8P 2                                                          
     D   Rate                         5P 2 VALUE                                                    
     D   Hours                       10U 0 VALUE                                                    
     D   Bonus                        5P 2 VALUE                                                    
      *                                                                                             
      * ワークフィールド                                                                                    
     D Pay             S              8P 2                                                          
      *                                                                                             
      * 出力条件制御用フラグの定義                                                                               
     Iemp_rec       99                                                                              
      *                                                                                             
      /free                                                                                         
         chain trn_number emp_rec;                                                                  
         if %found(EMPLOYEE);                                                                       
           pay = CalcPay (emp_rate: trn_hours: trn_bonus);                                          
         endif;                                                                                     
      /end-free                                                                                     
      *                                                                                             
      * 出力フィールドの定義                                                                                  
     OQSYSPRT   H    1P                  2  3                                                       
     O                                           35 'PAYROLL REGISTER'                              
     O                       *DATE         Y     60                                                 
     O          H    1P                  2                                                          
     O                                           60 Heading1                                        
     O          H    1P                  2                                                          
     O                                           60 Heading2                                        
     O          D   N1P 99               2                                                          
     O                       TRN_NUMBER           5                                                 
     O                       EMP_NAME            24                                                 
     O                       EMP_RATE      L     33                                                 
     O                       TRN_HOURS     L     40                                                 
     O                       TRN_BONUS     L     49                                                 
     O                       Pay                 60 '$     0.  '                                    
     O          D   N1PN99               2                                                          
     O                       TRN_NUMBER           5                                                 
     O                                           35 '** NOT ON EMPLOYEE FILE **'                    
     O          T    LR                  2                                                          
     O                                           33 'END OF LISTING'                                
      *                                                                                             
      * サブプロシージャ処理の定義                                                                               
     P CalcPay         B                                                                            
     D CalcPay         PI             8P 2                                                          
     D   Rate                         5P 2 VALUE                                                    
     D   Hours                       10U 0 VALUE                                                    
     D   Bonus                        5P 2 VALUE                                                    
     D  OverTime       S              5P 2 INZ(0)                                                   
      *                                                                                             
      /free                                                                                         
          if Hours > 40;                                                                            
            OverTime = (Hours - 40) * Rate * 1.5;                                                   
            Hours = 40;                                                                             
          endif;                                                                                    
          return  Rate * Hours + Bonus + Overtime;                                                  
      /end-free                                                                                     
      *                                                                                             
     P CalcPay         E                                                                            

実行結果

[Top Pageに戻る]

Ads by TOK2