RPG

498. ハイブリッドな最新の開発手法

RPGの開発を進化させていくとCLPを融合させたフレキシブルな
ハイブリッドな開発が自由にできるようになる。
複数のプログラムに分割しなくてもハイブリッドな
開発であれば全体を見渡せる構造化されたプログラムを
開発することができるようになる。
_

このりように RPGの中で自由にCLPを呼んだりまたRPGに戻って
自由にRPGのソースに戻って演算を続行できるように
なるハイブリッド開発が苦も無くできるようになると
あなたはかなりの習熟度に達していると言えるだろう。
 
実際、ハイブリッド開発が必要な場面は現代の
最新の開発では珍しくないはずである。

■ 請求書をPDF化してメール送信したい

_

請求書をPDF化しようとすると得意先別にPDF化しなければ
ならないので売上データを読んで得意先が変わったら
そこでスプールを閉じてスプールをPDF化して
メール送信する。
RPGプログラムの途中でCLPを呼び出してPDF化とメール送信を
行って再度、次の得意先の売上データを読み込むと
いう作業が必要になる。

印刷ファイル: QPRINTはユーザー制御でプログラム中で
オープンしたりクローズする必要がある。

要点を解説するたろにあえてRPGソースのすべてではなく
一部ずつを紹介する。

0001.00 H DFTNAME(FAXHAT) DATEDIT(*YMD/) BNDDIR('QC2LE')                         
0002.00 F********** 注文書 FAX 送信 ******************************************   
0003.00 FHATTUL1   IF   E           K DISK                                       
0004.00 FSIREMT    IF   E           K DISK                                       
0005.00 FBUHINM    IF   E           K DISK                                       
0006.00 FQPRINT    O    F  132        PRINTER OFLIND(*INOF) USROPN               
0007.00 F                                     FORMLEN(66)                        
0008.00 F                                     FORMOFL(62)                        
0009.00 F**********************************************************************  

[解説]

まずファイル仕様書では QPRINTはご覧のように USROPN を指定しておいて
OSによる暗黙的なオープンではなくユーザーによるRPG内での明示的なオープンを
宣言しておくものとする。

0043.00 C*----------------------------------------------------+                                
0044.00 C     SETKEY        KLIST                                                              
0045.00 C                   KFLD                    HTSRCD                                     
0046.00 C                   KFLD                    HTDATE                                     
0047.00 C                   KFLD                    HTHTNO                                     
0048.00 C                   KFLD                    HTGYO                                      
0049.00 C*----------------------------------------------------+                                
0050.00 C                   MOVEA     *ALL'-'       LIN                                        
0051.00 C                   MOVEL     FROMSIR       HTSRCD                                     
0052.00 C                   MOVEL     DATEFROM      HTDATE                                     
0053.00 C                   MOVE      *LOVAL        HTHTNO                                     
0054.00 C                   MOVE      *LOVAL        HTGYO                                      
0055.00 C     SETKEY        SETLL     HATTUL1                                                  
0056.00 C                   DO        *HIVAL                                       DO-*HIVAL   
0057.00 C                   SETOFF                                       50                    
0058.00 C                   READ      HATTUL1                                50                
0059.00 C   50              LEAVE                                                              
0060.00 C     SETKEY        SETLL     HATTUL1                                                  

[解説]

次に発注ファイルを仕入先(HTSRCD)発注日(HTDATE)でセットして
読み取るのだが最初に発注レコードを読み取ったら
次のように仕入先(HTSRCD) + 発注日(HTDATE)だけで RAEDE で等しいものだけを
読み取る。
_

0061.00 C*----------------------------------------------------+                                   
0062.00 C     EQLKEY        KLIST                                                                 
0063.00 C                   KFLD                    HTSRCD                                        
0064.00 C                   KFLD                    HTDATE                                        
0065.00 C*----------------------------------------------------+                                   
0066.00 C                   EXSR      OVRPRTF                                                     
0067.00 C                   OPEN      QPRINT                               90                     
0068.00 C     *IN90         IFEQ      *OFF                                         QPRINT         
0069.00 C                   DO        *HIVAL                                         DO-*HIVAL-EQL
0070.00 C                   SETOFF                                       50                       
0071.00 C     EQLKEY        READE     HATTUL1                                50                   
0072.00 C   50              LEAVE                                                                 
0073.00 C                   SETOFF                                       99                       
0074.00 C     HTSRCD        CHAIN     SIREMT                             99                       
0075.00 C                   SETOFF                                       99                       
0076.00 C     HTBHCD        CHAIN     BUHINM                             99                       
0077.00 C*( 明細印刷 )                                                                            
0078.00 C*-------------------------------------------------------------------------+              
0079.00 C                   SETON                                        42        |              
0080.00 C                   EXSR      OUTPUT                                       |              
0081.00 C*-------------------------------------------------------------------------+              
0082.00 C                   ADD       1             KENSU             7 0           件数           
0083.00 C                   ENDDO                                                    DO-*HIVAL-EQL 
0084.00 C                   CLOSE     QPRINT                                 
0094.00 C                   EXSR      DLTOVR                       

[解説]

この処理がこのプログラムのメインであり同じ仕入先のデータだけを
読み取るようにしている。

0066.00 C                   EXSR      OVRPRTF                                                     
0067.00 C                   OPEN      QPRINT 

というようにオーバーレイを実行して QPRINTを初めて仕入先別にオープンして印刷して
終われば

0084.00 C                   CLOSE     QPRINT                                 
0094.00 C                   EXSR      DLTOVR 

のようにして QPRINTをクローズして DLTOVRでオーバーライドを終了している。
ここで OVRPRTF とは

0032.00 D SYSTEM          PR            10I 0 EXTPROC('system')       
0033.00 D   CMD                           *   VALUE OPTIONS(*STRING)  
0034.00                                                               
    :

0101.00 C******************************************************                                
0102.00 C     OVRPRTF       BEGSR                                                              
0103.00 C******************************************************                                
0104.00 C                   IF        OUTPUT_ = '*     ' OR                        OVRPRTF     
0105.00 C                             OUTPUT_ = '*MAIL '                                       
0106.00  /FREE                                                                                 
0107.00    SYSTEM('OVRPRTF FILE(QPRINT) HOLD(*YES) USRDTA('' 注文書 '') -                      
0108.00      SECURE(*YES) OVRSCOPE(*JOB)');                                                    
0109.00  /END-FREE                                                                             
0110.00 C                   ELSE                                                   OVRPRTF     
0111.00  /FREE                                                                                 
0112.00    SYSTEM('OVRPRTF FILE(QPRINT) USRDTA('' 注文書 '') -                                 
0113.00      SECURE(*YES) OVRSCOPE(*JOB)');                                                    
0114.00  /END-FREE                                                                             
0115.00 C                   ENDIF                                                  OVRPRTF     
0116.00 C                   ENDSR                                                              

のようにして SYSTEMプロシージャーの中で OVRPRTF … のCLコマンドを実行している。
SYSTEM関数は system というC言語の関数であるがこれは

0001.00 H DFTNAME(FAXHAT) DATEDIT(*YMD/) BNDDIR('QC2LE')

のように H-仕様書で バインド・ディレクトリー: BNDDIR(‘QC2LE’) のバインドを
定義しているので RPGの中で C言語の関数を呼び出すことが可能になっている。

■ RPGの中でCLコマンドを定義して実行する

_

さらにRPGの中でCLコマンドの命令文を動的に定義して実行する方法を紹介しよう。
この方法を取得すればRPGの中で自由にコマンド文を定義することができて
苦も無くRPG内部でコマンドを実行することができる。

0001.00 H DFTNAME(CRTDFUDSP) DATEDIT(*YMD/) BNDDIR('QC2LE')
 :

0115.00 D DSPDTA_         C                   CONST('CPYSRCF FROMFILE(DFUEXLIB/-
0116.00 D                                     QDSPSRC) TOFILE(QTEMP/QDSPSRC)  - 
0117.00 D                                     FROMMBR(DSPDTA%s) -               
0118.00 D                                     TOMBR(%s) MBROPT(*ADD)')          
0119.00                                                                         
 :
0200.00 D CMD             PR            10I 0 EXTPROC('system')                    
0201.00 D  CMDSTR                         *   VALUE                                
0202.00 D                                     OPTIONS(*STRING)                     
0203.00 D RC              S             10I 0                                      
0204.00                                                                            
0205.00 D SPRINTF         PR            10I 0 EXTPROC('sprintf')                   
0206.00 D  BUFF                      32767A   OPTIONS(*VARSIZE)                    
0207.00 D  FORMAT                         *   VALUE OPTIONS(*STRING)               
0208.00 D  VAR                            *   VALUE OPTIONS(*NOPASS:*STRING:*TRIM) 
0209.00 D  VAR                            *   VALUE OPTIONS(*NOPASS:*STRING:*TRIM) 
0210.00                                                                            
 :
 /FREE               
    CMDSTR = *BLANKS;
    sprintf(CMDSTR:HEADER:FMTNO:DFU);
  CMD(CMDSTR); 
 /END-FREE

[解説]

ここでは sprintf というC言語の関数を使ってコマンドの文字列を組み立てている。

 0115.00 D DSPDTA_         C                   CONST('CPYSRCF FROMFILE(DFUEXLIB/-
0116.00 D                                     QDSPSRC) TOFILE(QTEMP/QDSPSRC)  - 
0117.00 D                                     FROMMBR(DSPDTA%s) -               
0118.00 D                                     TOMBR(%s) MBROPT(*ADD)')          
0119.00 

で定義されている文字列 DSPDTA_ の %s という記号がふたつ定義されているが
この %s という記号に FMTNO と DFU というファイールドの値を代入して CMDSTR を生成するのが

  sprintf(CMDSTR:HEADER:FMTNO:DFU);

という命令である。
そのあとに CMD(CMDSTR) によってコマンドを実行している。

このように C言語の関数 sprintf を使うとコマンドの変数部分に値を代入してコマンドの
文字列を動的に自由に作ることができる。

注意点として代入する変数 CMDSTRは前の実効値が必ず残ってしまうので
仕様する前に必ず

 CMDSTR = *BLANKS;

のようにして消去しておくひとが必要である。

RPG開発の経験がな豊富な開発者でもこのようにRPG内部でコマンドやCLPを実行した経験は
あまりないと思うがハイブリッドな開発が苦も無くできるようになると
開発の幅が一層広がることになる。
_

ハイブリッドな開発は今、時代の最先端である。