最初のページに戻ります。

総合の目次があるページに戻ります。

よく使うマニュアルです

Wiki

updated on 2004.06.23

17.17.特別講義:サブルーチン

[ Previous ] [ HOME ] [ Upper ] [ Next ]


サブルーチンとは何か

サブルーチンは、プログラム開発で、とても重要な記述方法です。呼び名は違うかもしれませんが、だいたいどんな言語にも、有るはずです。サブルーチンは、呼び出されると、開始から終了まで実行して、呼び出した行の次の行に戻ります。この「戻る」と言う機能が、重要です。サブルーチンを呼び出すと、プログラムは勝手に呼び出した場所を覚えていて、その場所の次に「戻る」のです。GOTO命令による分岐は、行ったら、行きっぱなしです。

プログラムの内部に定義されるサブルーチンを、「内部サブルーチン」と言います。単にサブルーチンと言ったら、これを指しています。また、別のプログラム(S)自体をサブルーチンに見立てて、プログラム(M)から呼び出す場合、呼び出されるプログラム(S)を「外部サブルーチン」と呼びます。よく「外サブ」とか言います。

ここでは、「内部サブルーチン」を取り上げています。「外部サブルーチン」は、サブルーチンとしての性格や使用目的などは、共通です。(だから同じサブルーチンと言う名前が付いているのですよね)

さて、そのサブルーチンの動きをよく見て下さい。「制御」とは、プログラムの実行点と考えて下さい。さらに、サブルーチンから戻った後、サブルーチンの定義域に、入り込んでいないことにも注意して下さい。

<IMG SRC="../flash3j/subroutine.gif" WIDTH=320 HEIGHT=460 BORDER=0>

RPGでの記述の仕方

RPGでは、C仕様書で使われます。記述する場合、必ず、C仕様書の最後に記述しなくてはなりません。また、サブルーチンの呼び出しは、C仕様書のどこからでも(明細演算、合計演算、サブルーチン定義内)呼び出せます。

尚、制約事項として、サブルーチンの個数は、1つのプログラムにつき最大 254です。

C 明細演算
合計演算 レベル制御標識
最終レコード標識
サブルーチンの定義
O

出力指定

関連する命令語

EXSR (多分、Execute Subroutine)

サブルーチンの呼び出し

条件標識 演算項目1 命令語 演算項目2 結果 結果フィールド属性 結果の標識
    EXSR サブルーチン名      

CASxx  (Compare And execute Subroutine)

サブルーチンの条件付き呼出し。ENDCS命令によってCASグループの終わりが示されます。

条件標識 演算項目1 命令語 演算項目2 結果 結果フィールド属性 結果の標識
  被比較値 CASxx 被比較値 サブルーチン名   HI LO EQ

BEGSR  (Beginning of Subroutine)

サブルーチン名の指定(演算項目1)と、その開始の宣言

条件標識 演算項目1 命令語 演算項目2 結果 結果フィールド属性 結果の標識
  サブルーチン名 BEGSR        

ENDSR (End of Subroutine)

サブルーチンの終了と、エラー処理後の戻り点の指定

条件標識 演算項目1 命令語 演算項目2 結果 結果フィールド属性 結果の標識
  タグ名 ENDSR エラー復帰      

サブルーチンあれこれ

  1. サブルーチンへは、基本的に、明示的にサブルーチンに行くことを指定(EXSR)しない限り、勝手にサブルーチンに行くことは有りません。

  2. この動きの例外的なサブルーチンは、*INZSR,*PSSRやファイル例外サブルーチンです。これらは、勝手に呼び出されます。(明示的に呼び出すことも可能です)。

  3. サブルーチンの中から、別のサブルーチンへ、とばすことも可能です。

  4. 戻り点は、原則的に、呼び出し(EXSR)行の、次の行に戻ります。

  5. エラーが有った場合に呼び出される、特殊なサブルーチン(*PSSRやファイル例外サブルーチン)の場合は、戻りポイントを、限定されたRPGサイクルの戻り点に合わせて、指定できます(タグ名や行番号は出来ません)。

  6. サブルーチンから、「同じ」サブルーチンを呼び出すことは出来ません。

  7. サブルーチンから、別のサブルーチンの中へ分岐、または明細や合計処理行へ分岐(GOTO)、をする事は出来ません。コンパイルエラーとなります。分岐命令は、そのサブルーチン内に限定されます。また、ENDSRの演算項目1にタグ名を指定して、そのサブルーチンで分岐先として指定できます。(ENDSRまでは、そのサブルーチンと同じと見なされている。)

どんな場合に使うのか

繰り返し使うロジックを、簡略化したい場合が最も多いでしょう。日付の妥当性検査とか、特別あつらえの関数の定義とか、更新処理とか。下のソースを参考にして下さい。この際、このソースがなにをしているか、なんて、読まず(どのみち、このままでは動きません。)、上のソースの無駄な繰り返しが、下のソースできれいにまとまっている点に注意して下さい。

     C******************************************************
     C*             M A I N -  R O U T I N E               :
     C******************************************************
     C* 右寄せ処理1
     C                     MOVE *BLANK    POLT1            ;
     C           ' '       CHEKRPILT1     STRLEN  30       ;
B001 C           STRLEN    IFGE PILEN                      ;
 001 C                     MOVELPILT4     POLT1            ;
+001 C                     ELSE                            ;
 001 C           PILEN     SUB  STRLEN    MGN     30       ;
 001 C                     CAT  PILT1:MGN POLT1            ;
E001 C                     END                             ;
     C* 右寄せ処理2                                        :
     C                     MOVE *BLANK    POLT2            ;
     C           ' '       CHEKRPILT2     STRLEN           ;
B001 C           STRLEN    IFGE PILEN                      ;
 001 C                     MOVELPILT4     POLT2            ;
+001 C                     ELSE                            ;
 001 C           PILEN     SUB  STRLEN    MGN              ;
 001 C                     CAT  PILT2:MGN POLT2            ;
E001 C                     END                             ;
     C* 右寄せ処理3                                        :
     C                     MOVE *BLANK    POLT3            ;
     C           ' '       CHEKRPILT3     STRLEN           ;
B001 C           STRLEN    IFGE PILEN                      ;
 001 C                     MOVELPILT4     POLT3            ;
+001 C                     ELSE                            ;
 001 C           PILEN     SUB  STRLEN    MGN              ;
 001 C                     CAT  PILT3:MGN POLT3            ;
E001 C                     END                             ;
     C* 右寄せ処理4                                        :
     C                     MOVE *BLANK    POLT4            ;
     C           ' '       CHEKRPILT4     STRLEN           ;
B001 C           STRLEN    IFGE PILEN                      ;
 001 C                     MOVELPILT4     POLT4            ;
+001 C                     ELSE                            ;
 001 C           PILEN     SUB  STRLEN    MGN              ;
 001 C                     CAT  PILT4:MGN POLT4            ;
E001 C                     END                             ;
     C*                                                    :
     C                     MOVE *ON       *INLR            :
     C                     RETRN                           :
                     
上↑と下↓は同じ事
     C******************************************************
     C*             M A I N -  R O U T I N E               :
     C******************************************************
     C* 右寄せ処理1
     C                     MOVELPILT1     PILTR 
     C                     EXSR @RGHIT                     :
     C                     MOVELPOLTR     POLT1
     C* 右寄せ処理2
     C                     MOVELPILT2     PILTR 
     C                     EXSR @RGHIT                     :
     C                     MOVELPOLTR     POLT2
     C* 右寄せ処理3
     C                     MOVELPILT3     PILTR 
     C                     EXSR @RGHIT                     :
     C                     MOVELPOLTR     POLT3
     C* 右寄せ処理4
     C                     MOVELPILT4     PILTR 
     C                     EXSR @RGHIT                     :
     C                     MOVELPOLTR     POLT4
     C*                                                    :
     C                     MOVE *ON       *INLR            :
     C                     RETRN                           :
     C******************************************************
     C*             S U B   -  R O U T I N E                
     C******************************************************
     C*----------------------------------------------------*
     C           @RGHIT    BEGSR                           :
     C*----------------------------------------------------*
     C                     MOVE *BLANK    POLTR            ;
     C           ' '       CHEKRPILTR     STRLEN  30       ;
     C*                                                    ;
B001 C           STRLEN    IFGE PILEN                      ;
 001 C                     MOVELPILTR     POLTR            ;
+001 C                     ELSE                            ;
 001 C           PILEN     SUB  STRLEN    MGN     30       ;
 001 C                     CAT  PILTR:MGN POLTR            ;
E001 C                     END                             ;
     C*                                                    :
     C                     ENDSR                           :
                     

参考として、実行順序を示します。左端の番号は、実行の順番を表しています。

     C******************************************************
     C*             M A I N -  R O U T I N E               :
     C******************************************************
 1   C                     EXSR @RGHIT                     :
     C*                                                    :
 12  C                     MOVE *ON       *INLR            :
 13  C                     RETRN                           :
-END-C******************************************************
     C*             S U B   -  R O U T I N E                
     C******************************************************
     C*----------------------------------------------------*
 2   C           @RGHIT    BEGSR                           :
     C*----------------------------------------------------*
 3   C                     MOVE *BLANK    POLTR            ;
 4   C           ' '       CHEKRPILTR     STRLEN  30       ;
     C*                                                    ;
 5   C           STRLEN    IFGE PILEN                      ;
 6   C                     MOVELPILTR     POLTR            ;
 7   C                     ELSE                            ;
 8   C           PILEN     SUB  STRLEN    MGN     30       ;
 9   C                     CAT  PILTR:MGN POLTR            ;
10   C                     END                             ;
     C*                                                    :
11   C                     ENDSR                           :   

また、その拡張的な利用として、機能をひとまとめにして(モジュール化といいます)、メインから、そのモジュールであるサブルーチンを、呼び出すことで、ロジックを明確にすることも良くあります。でも、モジュールを余り細かくして、サブルーチンの嵐にしてしまっては、全く意味がありません。この辺は、バランス感覚と、「普通はどうするものか」といったプログラムセンスが必要です。

     C******************************************************
     C*             M A I N -  R O U T I N E               :
     C******************************************************
  1  C           F3        DOUEQPUSHED                     :
  2  C                     EXSR @DSPFM                     :
  7  C           F3        IFNE PUSHED                     :
     C*                                                    :
  8  C                     EXSR @CKDAT                     :
     C*                                                    :
 12  C           V1ERR     IFNE *BLANK                     :
 13  C                     EXSR @MSG                       :
 17  C                     END                             :
     C*                                                    :
 18  C                     END                             :
 19  C                     END                             :
     C*                                                    :
     C                     MOVE *ON       *INLR            :
-end-C                     RETRN                           :
     C******************************************************
     C*             S U B   -  R O U T I N E                
     C******************************************************
     C*----------------------------------------------------*
  3  C           @DSPFM    BEGSR                           :
     C*----------------------------------------------------*
  4  C                     EXFMTFMT01                      :
  5  C        (F3は押していないと仮定します)             :
     C*                                                    :
  6  C                     ENDSR                           :
     C*----------------------------------------------------*
  9  C           @CKDAT    BEGSR                           :
     C*----------------------------------------------------*
 10  C                     MOVE 'XXX0101' V1ERR            :
     C*                                                    :
 11  C                     ENDSR                           :
     C*----------------------------------------------------*
 14  C           @MSG      BEGSR                           :
     C*----------------------------------------------------*
 15  C                      ...                            :
     C*                                                    :
 16  C                     ENDSR                           :
                            

@DSPFMでは、画面を表示して、応答を待つ、という機能を独立(モジュール化)して、定義した例です。機能的なロジックをまとめて、ロジックを簡略にしようとしています。

@CKDATでは、日付検査ルーチンという部分を独立(モジュール化)して、定義した例とも言えますし、繰り返しを避けている、とも言えます。どちらもサブルーチンの特徴です。

@MSGでは、メッセージのテキストなどの設定などの処理を、独立(モジュール化)して、定義した例とも言えますし、繰り返しを避けているとも言えます。どちらもサブルーチンの特徴です。

特殊なサブルーチン

ここから先は、将来の知識として、読んでおいてください。予備校レベルでは、不要です

このほかに、サブルーチンの名前(BEGSRの有る行の、演算項目1)に特殊なものが有ります。働きや指定が特殊です。「大抵の場合」、記述の際は、C仕様書で、EXSRは使いません。プログラムが勝手に、処理をする部分の定義と考えて下さい。

*INZSR初期設定サブルーチン

プログラムの初期設定時に実行される特定のサブルーチンを指定するために、そのサブルーチンの BEGSR命令の演算項目1に *INZSR を指定することができます。初期設定サブルーチンとして指定できるサブルーチンは1つだけです。このサブルーチンはプログラム・サイクルのプログラム初期設定ステップ終了時に(自動的に)呼び出されます(すなわち、データ構造およびサブフィールドが初期設定され、外部標識およびユーザー・データ・フィールドが検索され、ファイルがオープンされ、データ域データ構造、配列、およびテーブルがロードされ、*ENTRY PLIST の PARM 結果フィールドが演算項目1へ転送された後になります)。*INZSR をファイル/プログラム・エラー/例外サブルーチンに指定することはできません。

ファイルの例外/エラー・サブルーチン (INFSR)

ファイルの例外/エラーが発生した後で制御を受け取れるようにユーザーが作成した RPG/400 サブルーチンを識別するためには、ファイル仕様書の継続記入行(または主要ファイル記入行)に以下の項目を記入します。

記入項目

6

F (F仕様書のこと)

7 〜 52

ブランク(情報を別の継続記入行に指定した場合)

53

K(継続ステートメントであることを示します。)

54 〜 59

INFSR

60 〜 65

このファイルで例外/エラーが発生した場合に制御が渡されるサブルーチンの名前。

サブルーチン名を *PSSRとすることはできますが、これはこのファイルの例外/エラーによってプログラムの例外/エラー・サブルーチンに制御が移ることを示します。

プログラムの例外/エラー : *PSSR

プログラムの例外/エラーの発生時に制御を受け取るユーザー作成のRPG/400 サブルーチンを識別するには、サブルーチンのBEGSR 演算項目1に *PSSR と指定します。命令コードの 56 〜 57 桁目に標識を指定していない場合には、プログラムの例外/エラーが発生すると制御がこのサブルーチンに渡されます。またサブルーチンは EXSR 命令から呼び出すこともできます。ファイルの例外/エラー・サブルーチンのファイル仕様書の継続記入行( 54〜 59 桁目に INFSR )の 60 〜 65 桁目に*PSSR と指定して、ファイルの例外/エラーが発生した場合に制御が渡されるようにすることができます。

上記特殊なサブルーチンの指定例

     FQRYF    IF  F       1            DISK         
     F                                              KINFSR @EXERR
     FARVF    IF  F    9500            DISK         KINFSR @EXERR
     FUPDF    UF  F    9500            DISK         KINFSR @EXERR
     
     C                      ....                            
     
     C*----------------------------------------------------*
     C           *INZSR    BEGSR                           :
     C*----------------------------------------------------*
     C                     ....                            :
     C*                                                    :
     C                     ENDSR                           :
     C*----------------------------------------------------*
     C           @EXERR    BEGSR                           :
     C*----------------------------------------------------*
     C                     MOVEL'*DETC'   RETURN  6        :
     C                     ....                            :
     C*                                                    :
     C                     ENDSRRETURN                     :
     C*----------------------------------------------------*
     C           *PSSR     BEGSR                           :
     C*----------------------------------------------------*
     C           SWP       IFEQ *ON                        :
     C                     DUMP                            :
     C                     MOVE *ON       *INH1            :
     C                     RETRN                           :
     C                     ELSE                            :
     C                     MOVE *ON       SWP     1        :
     C                     END                             :
     C*                                                    :
     C                     ENDSR'*DETC'                    :
                    

RPG/400 例外/エラー処理ルーチン詳細も参考にして下さい。

1998/10/31


[ Previous ] [ HOME ] [ Upper ] [ Next ]

You are at K's tips-n-kicks of AS/400

 

SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送