RPG

370. サービス・プログラムの作成

「プロシージャーを公開する」ではプロシージャーを含むプログラムを

CRTRPGMOD + SRVSRVPGM

によってサービス・プログラムを生成した。
つまり本来はプログラムとして動作していたモジュールのソースを使って
サービス・プログラム(*SRVPGM)を作成したのだがこれでよいのだろうか?

始めからサービス・プログラム(*SRVPGM)として開発する場合は
少し様子がちがう。
RPGソース: TESTPROC には次のようなメイン・ルーチンが存在していたことを
思い出して欲しい。

   :
0025.00 C*( メイン・ルーチンの始まり )                                      
0026.00 C                   CALLP     SNDPGMMSG(MSR(1))                     
0027.00 C                   SETON                                        LR 
0028.00 C                   RETURN                                          
0029.00 C*( メイン・ルーチンの終わり )                                      
  :

ところで

CRTRPGMOD + SRVSRVPGM

としてサービス・プログラム(*SRVPGM)を生成する場合はこのメイン・ルーチンは
全く機能していないはずである。
従ってサービス・プログラム(*SRVPGM)として作成する場合のソースは
次のようになる。

[ サービス・プログラム: TESTSRV ]

ソースはこちらから

0001.00 H NOMAIN                                                                           
0002.00 F********** サービス・プログラム **************************************            
0003.00 F*                                                                                 
0004.00 F**********************************************************************            
0005.00                                                                                    
0006.00  * CRTRPGMOD  OBJ(QTEMP/TESTSRV)   SRCFILE(R610SRC/QRPGLESRC)                      
0007.00  * DBGVIEW(*SOURCE) AUT(*ALL)                                                      
0008.00                                                                                    
0009.00  * CRTSRVPGM SRVPGM(OBJLIB/TESTSRV) MODULE(QTEMP/TESTSRV) SRCFILE(SRCLIB/QSR       
0010.00  * VSRC) ACTGRP(*CALLER) AUT(*ALL)                                                 
0011.00                                                                                    
0012.00  *-------------------------------------------------------------------*             
0013.00  *  2020/08/09 : 作成                                                              
0014.00  *-------------------------------------------------------------------*             
0015.00  *( 作業変数 )                                                                     
0016.00 D MSR             S             80    DIM(1) CTDATA PERRCD(1)               配列   
0017.00 D AR              S              1A   DIM(256)                                     
0018.00 D N               S              4S 0                                              
0019.00                                                                                    
0020.00  ****************************************************                              
0021.00  *       プロシージャーのプロトタイプ宣言           *                              
0022.00  ****************************************************                              
0023.00 D*( SNDPGMMSG     のプロトタイプ宣言 )                                             
0024.00 D SNDPGMMSG       PR                                            
0025.00 D  MSG                        3000A   Value                     
0026.00 D  MSGTYPE_IN                   10A   value OPTIONS(*NOPASS)    
0027.00 D  CALLSTACKC_IN                10I 0 CONST OPTIONS(*NOPASS)    
0028.00                                                                 
0029.00  ****************************************************           
0030.00  *       プロシージャーの本体の記述                 *           
0031.00  ****************************************************           
0032.00  *********************************************************      
0033.00  *   SNDPGMMSG:  メッセージを現在の CALLSTACK に送信     *      
0034.00  *********************************************************      
0035.00  *---( SNDPGMMSG PROCEDURE  ここから )------------------------* 
0036.00 P SNDPGMMSG       B                   EXPORT                    
0037.00 D                 PI                                            
0038.00 D  MSG                        3000A   Value                     
0039.00 D  MSGTYPE_IN                   10A   value OPTIONS(*NOPASS)    
0040.00 D  CALLSTACKC_IN                10I 0 CONST OPTIONS(*NOPASS)    
0041.00                                                                 
0042.00 D APIERR          DS                                            
0043.00 D  GETBYT                 1      4B 0 INZ(160)                  
0044.00 D  AVLBYT                 5      8B 0 INZ(0)                    
0045.00 D  MSGID                  9     15                              
0046.00 D  MSGDTA                17    160                              
0047.00                                                                 
0048.00 D QMHSNDPM        PR                  ExtPgm('QMHSNDPM')          
0049.00 D  MSGID                         7A   CONST                       
0050.00 D  MSGFILE                      20A   CONST                       
0051.00 D  MSGDATA                    6000A   CONST OPTIONS(*varsize)     
0052.00 D  MSGDATALEN                   10I 0 CONST                       
0053.00 D  MSGTYPE                      10A   CONST                       
0054.00 D  CALLSTACKE                   10A   CONST                       
0055.00 D  CALLSTACKC                   10I 0 CONST                       
0056.00 D  MSGKEY                        4A                               
0057.00 D  APIERR                             LIKEDS(APIERR)              
0058.00 D                                     OPTIONS(*VARSIZE)           
0059.00 D PARMS           S              4S 0                             
0060.00 D MSGKEY          S              4A                               
0061.00 D CALLSTACKC      S             10I 0 INZ(1)                      
0062.00 D MSGTYPE         S             10A   INZ('*DIAG     ')           
0063.00                                                                   
0064.00 C                   EVAL      PARMS = %PARMS()                    
0065.00 C                   SELECT                                        
0066.00 C                   WHEN      PARMS = 1                           
0067.00 C                   WHEN      PARMS = 2                           
0068.00 C                   EVAL      MSGTYPE = MSGTYPE_IN                
0069.00 C                   WHEN      PARMS = 3                           
0070.00 C                   EVAL      CALLSTACKC = CALLSTACKC_IN          
0071.00 C                   EVAL      MSGTYPE = MSGTYPE_IN                
0072.00 C                   ENDSL                                         
0073.00  /FREE                                                            
0074.00    QMHSNDPM('CPF9897':'QCPFMSG   *LIBL':MSG:                      
0075.00             %LEN(%TRIM(MSG)):MSGTYPE:'*PGMBDY':                   
0076.00             CALLSTACKC:MSGKEY:APIERR);                            
0077.00  /END-FREE                                                        
0078.00 C                   RETURN                                        
0079.00 P                 E                                               
0080.00  *---( SNDPGMMSG    PROCEDURE  ここまで )------------------------*



[解説]

サービス・プログラムなのでメイン・ルーチンはない。
それどころか

0001.00 H NOMAIN

としているのはRPGサイクルのモジュールも不要として除去されている。
若い開発者はご存知ないと思うがRPGはそのままコンパイルすると
自動的にRPGサイクルなるメイン・モジュールがコンパイラーによって
挿入される。
VisualBASICやVC++にも実はメイン・ルーチンはある。
それはこっそりとMicrosoftによってメイン・ルーチンが挿入されているに
過ぎない。
RPGの場合も同じで H NOMAIN はメイン・ルーチンの挿入を拒否している。

*INZSR という特殊な最初だけ実行されるサブ・ルーチンも実は
RPGサイクルの一部なので H NOMAIN を指示すると *INZSRサブ・ルーチンは
使えなくなるので念のため注意をされたい。

このように最初からサービス・プログラムの生成の基となるRPGソースには
メイン・ルーチンは記述しないのが基本である。
このソースから

CRTRPGMOD + CRTSRVPGM

を行えばよい。

これでサービス・プログラムの開発方法も理解して頂けたことと思う。