RPG

368. プロシージャーを呼び出す

先に作成したプロシージャーを呼び出す上位プログラムを
作成してみよう。

[プロシージャー呼出し:TESTCALL ]

ソースはこちらから

0001.00 H DFTNAME(TESTCALL) DATEDIT(*YMD/) BNDDIR('QC2LE')                               
0002.00 F********** プロシージャーの呼出し ************************************          
0003.00 F*                                                                               
0004.00 F**********************************************************************          
0005.00                                                                                  
0006.00  * CRTRPGMOD  OBJ(QTEMP/TESTCALL)   SRCFILE(R610SRC/QRPGLESRC)                   
0007.00  * DBGVIEW(*SOURCE) AUT(*ALL)                                                    
0008.00  * CRTPGM PGM(OBJLIB/TESTPROC) MODULE(QTEMP/TESTPROC)                            
0009.00  *        BNDSRVPGM(OBJLIB/TESTPROC) ACTGRP(*NEW) AUT(*ALL)                      
0010.00                                                                                  
0011.00  *-------------------------------------------------------------------*           
0012.00  *  2020/08/08 : 作成                                                            
0013.00  *-------------------------------------------------------------------*           
0014.00  *( 作業変数 )                                                                   
0015.00 D MSR             S             80    DIM(1) CTDATA PERRCD(1)               配列 
0016.00 D AR              S              1A   DIM(256)                                   
0017.00 D N               S              4S 0                                            
0018.00                                                                                  
0019.00 D*( SNDPGMMSG     のプロトタイプ宣言 )                                           
0020.00 D SNDPGMMSG       PR                                                             
0021.00 D  MSG                        3000A   Value                                      
0022.00 D  MSGTYPE_IN                   10A   value OPTIONS(*NOPASS)                     
0023.00 D  CALLSTACKC_IN                10I 0 CONST OPTIONS(*NOPASS)                     
0024.00                                                                     
0025.00 C*( メイン・ルーチンの始まり )                                      
0026.00 C                   CALLP     SNDPGMMSG(MSR(1))                     
0027.00 C                   SETON                                        LR 
0028.00 C                   RETURN                                          
0029.00 C*( メイン・ルーチンの終わり )                                      
0030.00                                                                     
0031.00 C******************************************************             
0032.00 C     *INZSR        BEGSR                                           
0033.00 C******************************************************             
0034.00 C*  初期 CYCLE のみの実行                                           
0035.00 C                   ENDSR                                           
0036.00 ** MSR -- 以下は配列                     
0037.00  これはプロシージャー呼出しのテストです。


 

[解説]

コンパイルは次のとおり

CRTRPGMOD MODULE(QTEMP/TESTCALL) SRCFILE(SRCLIB/QRPGLESRC) DBGVIEW(*SOURCE) AUT(*ALL)

CRTPGM PGM(OBJLIB/TESTCALL) MODULE(QTEMP/TESTCALL) BNDSRVPGM((OBJLIB/TESTPROC)) ACTGRP(*NEW) AUT(*ALL)

… CRTRPDMOD で QTEMP にモジュールを作成して CRTPGM で BNDSRVPGM((OBJLIB/TESTPROC)) で
サービス・プログラム(*SRVPGM)をバインドしてプログラムを作成する。

 ここで CRTPGMコマンドを注意してよく見てみると

                            プログラムの作成  (CRTPGM)                          
                                                                                
  選択項目を入力して,実行キーを押してください。                                
                                                                                
  サービス・プログラム のバインド :                                                    
    サービス・プログラム  . . . . > TESTPROC       名前,総称* , *NONE, *ALL   
     ライブラリー  . . . . . . . . . . >   TEST.COM     名前 , *LIBL                 
    活動化  . . . . . . . . . . .   *IMMED        *IMMED, *DEFER                
                 値の続きは+                                                   
  ディレクトリーのバインド  . . .   *NONE          名前 , *NONE                 
   ライブラリー  . . . . . . . . . . .                  名前 , *LIBL, *CURLIB...     
                 値の続きは+                                                   
                                                                                
  活動化グループ  . . . . . . . . > *NEW           名前 , *ENTMOD, *NEW, *CALLER
  作成オプション  . . . . . . . .                 *GEN, *NOGEN, *NODUPPROC...   
                 値の続きは+                                                   
  明細のリスト  . . . . . . . . .   *NONE         *NONE, *BASIC, *EXTENDED...   
  更新可能  . . . . . . . . . . .   *YES          *YES, *NO                     
 *SRVPGM ライブラリー更新可能   .   *NO           *YES, *NO                     
  ユーザー・プロファイル  . . . .   *USER         *USER, *OWNER                 
                                                                       続く ... 
 F3= 終了    F4=プロンプト   F5= 最新表示    F12= 取り消し                         
 F13= この画面の使用法                    F24= キーの続き                       

のようにして サービス・プログラムのバインドには

  サービス・プログラム のバインド :                                                    
    サービス・プログラム  . . . . > TESTPROC       名前,総称* , *NONE, *ALL   
     ライブラリー  . . . . . . . . . . >   TEST.COM     名前 , *LIBL                 
    活動化  . . . . . . . . . . .   *IMMED        *IMMED, *DEFER

 

のように省略値のバインド方法は *IMMED であるが *DEFER も指定できることがわかる。

*IMMED を指定するとプログラムがCPUにロードされると同時にサービス・プログラムも
同時にCPUメモリ内にロードされる。
しかし *DEFER を指定したときは、そのサービス・プログラム内のプロシージャーが
呼び出されるときに初めてサービス・プログラムもロードされることになる。
サービス・プログラムの数が多いときは *DEFER としてバインドすると
使用されなかったサービス・プログラムはロードされないので
無駄もないしメモリも節約されるし最初のロードは素早くなる。

このようにプログラムとそれを使用するサービス・プログラムは別々に管理される。

■プログラムとサービス・プログラムの分離

サービス・プログラムに変更があってサービス・プログラムを再作成しても
サービス・プログラムの記号が変わらない限りは上位のプログラムを
再コンパイルする必要はない。

■ ILE(=統合型開発環境)は複数言語のバインドを可能にする

このようなサービス・プログラムはRPGだけでなくCOBOLやC言語でも
開発することができる。
サービス・プログラムはどのような言語による開発でもかまわないし
異なる言語からのサービス・プログラムであってもバインドして
ひとつのプログラムに仕上げることができる。
これがILEと呼ばれる所以である。

■ i5/OS関数も多くはサービス・プログラムである

IBM iの英小文字のAPIやC言語の関数はサービス・プログラムのプロシージャーとして
提供されている。
このためRPGから英小文字APIやC言語関数を呼び出して使用することができる。
例えばIFSストリーム・ファイルのオープンや出力はC言語によるサービス・プログラムから
出来ているのだがRPGプログラムからそれらをバインドして利用することができる。

■ 社内のビジネス・ロジックをプロシージャー化すれば

社内独自のビジネス・ロジックは社内のアプリケーションにいくつも存在しているはずである。
例えば製品を受注したときに社内在庫にどのように引当てするかは基本的なロジックが
ある。
社内に在庫がなければ社外の置場預け在庫を検索してそれでもなければ仕入れ商品である場合は
発注済みの入庫予定から引当て可能在庫数を計算して ….という具合である。
社内の適用業務を設計しているときに社内のロジックは結構複雑であり
毎度、プログラムを書き直していたのではバグも出るし第一開発が大変である。
このような複雑なビジネス・ロジックは確実に動作するバグのないプロシージャーとして
作成しておけばどのプログラムからでもその品質が保証されたプロシージャーを
呼び出すだけで済む。
まさにオブジェクト指向である。
   社内に同じビジネス・ロジックが散在しているのではなくビジネス・ロジックは唯一で
品質保証されたオブジェクトであることが保守性の観点からも最も望ましい。

■ SOA の始まりはプロシージャー化から

少し前に流行しかけたSOA(=Service Oriented Archtechture) というのは
ビジネス・ロジックをXMLでエクスポート(公開)してそれらを
XMLでバインドしたり再利用するシステムのことを言う。
社内システムをSOA化しておけば新しい要望が出ても社内のXMLから
要望の実現のための時間が短くて済むというものでIBMが銀行などに
数億円のSOA化を提案していたがSOA化するための時間とコストが
かかりすぎで今ではSOAの名前すら出てこない。

しかしビジネス・ロジックをXMLとしてEXPORTしようという発想は
正しい方向であることはまちがいない。

■ Webサービスもプロシージャーで

プロシージャーをXMLとしてEXPORTするとJavaScriptからRPGで開発された
プロシージャーを呼び出すことができるようになる。
つまりブラウザ上でRPGのロジックが動作することになる。
このようにWebで公開されるビジネス・ロジックのことを
Webサービスと言う。
Webサービスは既に普及していて例えば天気予報や郵便番号による住所検索である。
弊社製品AutoWebでも

   ・カレンダー検索
DSPFのDDSソースに日付フィールドに編集コードYまたはWを指定しておくと
カレンダー・コントロールを表示して選択することができる。

・郵便番号による住所検索
郵便番号を入力するだけで日本中の住所を検索することができる。

…カレンダーや郵便番号を自社で保守する必要はない。
このような機能が既にWebサービスとして公開されているので
HTMLインターフェースで利用することができるのである。

  …このようにプロシージャーによる再利用は適用業務の利用範囲を大幅に広げてくれる。
しかしILEで誤った使い方もあるので次回はその注意点について解説を予定している。