渡されるパラメーターの数の検査

呼び出しで渡されるパラメーター数の検査を必要とする場合があります。 プロシージャーの作成方法により、この数によって、渡されないパラメーター を参照せずに済むことがあります。例えば、3 つのパラメーターを渡される時もあれば、4 つのパラメーターを渡 される時もあるプロシージャーを作成するとします。 このことは、新しいパラメーターが必要となった時に 起こります。 呼び出されるプロシージャーを書いて、組み込み関数 %PARMS によって戻される値に従ってどちらの数も処理することができます。 新しい呼び出しでは、このパラメーターが渡されます。 元からの呼び出しは変更されないままです。

%PARMS はパラメーターを使用しません。 %PARMS によって戻される値には *OMIT が渡されるパラメーターも 含まれます。 *PARMS フィールドを使用するためには PSDS もコーディングしなければなり ませんが、メイン・プロシージャーでは、%PARMS は PSDS の *PARMS フィールドに入っているのと 同じ値を戻します。

*PARMS と %PARMS の両方で、渡されたパラメーターの数が分からない場合には、値 -1 が 戻されます (渡されたパラメーターの数を判別するには、少なくとも操作記述子を渡さなけ ればなりません。ILE RPG は常に呼び出しでこれを渡しますが、他の ILE 言語では渡さない場合があります)。 メイン・プロシージャーが活動状態になっていない場合には、 *PARMS は信頼できません。 サブプロシージャーから *PARMS を参照することは望ましくありません 。

%PARMS の使用

この例では、会社の社員の住所情報の変更に使用するため、 プロシージャー FMTADDR が数回変更されています。FMTADDR は 3 つの異なるプロシージャーによって呼び出されます。 プロシージャーは、社員情報を処理するのに使用するパラメーターの数だけが 異なります。すなわち、FMTADDR に対する新たな必要性が起こり、それらをサポートするために 、新しいパラメーターが追加されました。 しかし、FMTADDR を呼び出す旧プロシージャーはまだサポートされており、 変更したりコンパイルし直したりする必要はありません。

社員の住所の変更は、次のように要約することができます。

プロシージャーは渡されたパラメーター数を基にして情報を 処理します。 数は 3 から 5 の間で変わることがあります。 この数により、プログラムに市または県、あるいはその両方のデフォルト値を提供するかどうかが通知されます。図 69 は、このプロシージャーのソースを示したものです。図 70 は、 /COPY メンバーがこのプロトタイプを含んでいる場合のソースです。

FMTADDR の主ロジックは、次のとおりです。

  1. %PARMS を使用して、渡されたパラメーターの数を検査する。 この組み込み関数は、渡されたパラメーターの数を戻します。
  2. サブルーチン GetStreet# を使用して、番地を印刷用に訂正する。
  3. 完全な住所を連結する。
  4. 戻る。
図 69. プロシージャー FMTADDR のソース
      *=================================================================*
      * FMTADDR - 住所の形式設定
      *
      * インターフェース・パラメーター
      * 1. 住所         文字 (70)
      * 2. 番地         パック (5,0)
      * 3. 町名         文字 (20)
      * 4. 市区町村     文字 (15)   (呼び出し元によっては渡されない場合もある)
      * 5. 都道府県     文字 (15)   (呼び出し元によっては渡されない場合もある)
      *=================================================================*
      * /COPY メンバーからプロトタイプを取り込みます
      /COPY  FMTADDRP
     DFmtAddr          PI
     D Address                       70
     D Street#                        5  0 CONST
     D Street                        20    CONST
     D P_City                        15    OPTIONS(*NOPASS) CONST
     D P_Province                    15    OPTIONS(*NOPASS) CONST
      *-----------------------------------------------------------------*
      * 渡されない可能性のあるパラメーターのデフォルト値
      *-----------------------------------------------------------------*
     D City            S             15    INZ('Toronto')
     D Province        S             15    INZ('Ontario')
      *-----------------------------------------------------------------*
      * 都道府県 (Province) パラメーターが渡されたかどうかを検査します。
      * 渡された場合には、デフォルト値をパラメーター値で置き換えます。
      *-----------------------------------------------------------------*
     C                   IF        %PARMS > 4
     C                   EVAL      Province = P_Province
     C                   ENDIF
      *-----------------------------------------------------------------*
      * 市区町村 (City) パラメーターが渡されたかどうかを検査します。
      * 渡された場合には、デフォルト値をパラメーター値で置き換えます。
      *-----------------------------------------------------------------*
     C                   IF        %PARMS > 3
     C                   EVAL      City = P_City
     C                   ENDIF
      *-----------------------------------------------------------------*
      * 'CStreet#' を 'Street#' の文字形式に設定します。                *
      *-----------------------------------------------------------------*
     C                   EXSR      GetStreet#
      *-----------------------------------------------------------------*
      * 住所を番地、町名、市区町村、都道府県の形式に設定します。        *
      *-----------------------------------------------------------------*
     C           EVAL     ADDRESS = %TRIMR(CSTREET#) + ' ' +
     C                              %TRIMR(CITY) + ' ,' +
     C                              %TRIMR(PROVINCE)
     C                   RETURN
      *=================================================================*
      * サブルーチン: GetStreet#
      * 番地の文字形式を入手し、左寄せして、右にブランクを              *
      * 埋め込みます。                                                  *
      *=================================================================*
     C     GetStreet#    BEGSR
     C                   MOVEL     Street#       CStreet#         10
      *-----------------------------------------------------------------*
      * 最初の非ゼロを検出します。                                      *
      *-----------------------------------------------------------------*
     C     '0'           CHECK     CStreet#      Non0              5 0
      *-----------------------------------------------------------------*
      * 非ゼロがあった場合には、非ゼロで始まる番地のサブストリングを    *
      * 作成します。                                                    *
      *-----------------------------------------------------------------*
     C                   IF        Non0 > 0
     C                   SUBST(P)  CStreet#:Non0 CStreet#
      *-----------------------------------------------------------------*
      * 非ゼロがない場合には、番地として '0' だけを使用します。         *
      *-----------------------------------------------------------------*
     C                   ELSE
     C                   MOVEL(P)  '0'           CStreet#
     C                   ENDIF
     C                   ENDSR
図 70. プロシージャー FMTADDR のプロトタイプでの /COPY メンバーのソース
      *=================================================================*
      * FMTADDR のプロトタイプ - 住所の形式設定
      *=================================================================*
     DFmtAddr          PR
     D  addr                         70
     D  strno                         5  0 CONST
     D  st                           20    CONST
     D  cty                          15    OPTIONS(*NOPASS) CONST
     D  prov                         15    OPTIONS(*NOPASS) CONST

図 71 にはプロシージャー PRTADDR のソースを示してあります。このプロシージャーは、FMTADDR の使用を 説明するために提供されます。 便宜上、それぞれに FMTADDR を呼び出す 3 つのプロシージャーがこの 1 つの プロシージャーに結合されています。また、この例のデータはプログラム記述です。

PRTADDR は '3 つのプロシージャーを 1 つにまとめている' ので、 異なる 3 つの住所データ構造を定義しなければなりません。 同様に、演算仕様書に 3 つの部分があり、 それぞれが各段階でプログラムと対応しています。 住所の印刷後、プロシージャー PRTADDR は終了します。

図 71. プロシージャー PRTADDR のソース
      *=================================================================*
      * PRTADDR - 住所の印刷
      *           住所を形式設定するために FmtAddr を呼び出す
      *=================================================================*
     FQSYSPRT   O    F   80        PRINTER
      *-----------------------------------------------------------------*
      * FmtAddr のプロトタイプ
      *-----------------------------------------------------------------*
     DFmtAddr          PR
     D  addr                         70
     D  strno                         5  0
     D  st                           20
     D  cty                          15    OPTIONS(*NOPASS)
     D  prov                         15    OPTIONS(*NOPASS)
     DAddress          S             70
      *-----------------------------------------------------------------*
      * ステージ 1: 元の住所のデータ構造。
      * 町名および番地だけが可変情報。
      *-----------------------------------------------------------------*
     D Stage1          DS
     D   Street#1                     5P 0 DIM(2) CTDATA
     D   StreetNam1                  20    DIM(2) ALT(Street#1)
      *-----------------------------------------------------------------*
      * ステージ 2: 市区情報を可変とした
      * 改訂住所データ構造。
      *-----------------------------------------------------------------*
     D Stage2          DS
     D   Street#2                     5P 0 DIM(2) CTDATA
     D   Addr2                       35    DIM(2) ALT(Street#2)
     D     StreetNam2                20    OVERLAY(Addr2:1)
     D     City2                     15    OVERLAY(Addr2:21)
      *-----------------------------------------------------------------*
      * ステージ 3: 都道府県情報を可変とした
      *  改訂住所データ構造。
      *-----------------------------------------------------------------*
     D Stage3          DS
     D   Street#3                     5P 0 DIM(2) CTDATA
     D   Addr3                       50    DIM(2) ALT(Street#3)
     D     StreetNam3                20    OVERLAY(Addr3:1)
     D     City3                     15    OVERLAY(Addr3:21)
     D     Province3                 15    OVERLAY(Addr3:36)
      *-----------------------------------------------------------------*
      * 'プログラム 1'- 市区パラメーターの追加前の FMTADDR の使用。
      *-----------------------------------------------------------------*
     C                   DO        2             X                 5 0
     C                   CALLP     FMTADDR (Address:Street#1(X):StreetNam1(X))
     C                   EXCEPT
     C                   ENDDO
      *-----------------------------------------------------------------*
      * 'プログラム 2'- 都道府県パラメーター追加前の FMTADDR の使用。   *
      *-----------------------------------------------------------------*
     C                   DO        2             X                 5 0
     C                   CALLP     FMTADDR (Address:Street#2(X):
     C                             StreetNam2(X):City2(X))
     C                   EXCEPT
     C                   ENDDO
      *-----------------------------------------------------------------*
      * 'プログラム 3' - 都道府県パラメーター追加後の FMTADDR の使用。  *
      *-----------------------------------------------------------------*
     C                   DO        2             X                 5 0
     C                   CALLP     FMTADDR (Address:Street#3(X):
     C                             StreetNam3(X):City3(X):Province3(X))
     C                   EXCEPT
     C                   ENDDO
     C                   SETON                                        LR
      *-----------------------------------------------------------------*
      * 住所の印刷。                                                    *
      *-----------------------------------------------------------------*
     OQSYSPRT   E
     O                       Address
**
00123Bumble Bee Drive
01243Hummingbird Lane
**
00003Cowslip Street      Toronto
01150Eglinton Avenue     North York
**
00012Jasper Avenue       Edmonton       Alberta
00027Avenue Road         Sudbury        Ontario

これらのプログラムを作成するためには、次のステップに従ってください。

  1. 図 69 のソースを使って FMTADDR を作るには、以下のように入力します。
    CRTRPGMOD MODULE(MYLIB/FMTADDR)
  2. PRTADDR を作成するために、図 71 のソースを使用して、次のよ うに入力してください。
    CRTRPGMOD MODULE(MYLIB/PRTADDR)
  3. プログラム PRTADDR を作成するために、次のように入力してください。
    CRTPGM PGM(MYLIB/PRTADDR) MODULE(PRTADDR FMTADDR)
  4. PRTADDR を呼び出します。 出力を以下に示します。
    123 Bumble Bee Drive, Toronto, Ontario
    1243 Hummingbird Lane, Toronto, Ontario
    3 Cowslip Street, Toronto, Ontario
    1150 Eglinton Avenue, North York, Ontario
    12 Jasper Avenue, Edmonton, Alberta
    27 Avenue Road, Sudbury, Ontario