ILE RPG プログラムの例

この節では、給与計算を実行する簡単な ILE RPG プログラムを説明します。

問題文

ある小さい会社の給与計算部門では、その週の社員の給与をリストする印刷出 力を作成したいとします。 システム上には EMPLOYEE と TRANSACT の 2 つのディスク・ファイルが あるとします。

最初のファイル EMPLOYEE には社員のレコードが入っています。 下の図は社員レコードの形式を示しています。

図 1. 社員物理ファイルの DDS
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ..*
A..........T.Name++++++RLen++TDpB......Functions++++++++++++++++++++*
A          R EMP_REC
A            EMP_NUMBER     5          TEXT('EMPLOYEE NUMBER')
A            EMP_NAME      16          TEXT('EXPLOYEE NAME')
A            EMP_RATE       5  2       TEXT('EXPLOYEE RATE')
A          K EMP_NUMBER

2 番目のファイル TRANSACT には、各社員がその週に働いた時間数とその社員が 受け取ったボーナスが記録されています。 下の図はトランザクション・レコードの形式を示しています。

図 2. TRANSACT 物理ファイルの DDS
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ..*
A..........T.Name++++++RLen++TDpB......Functions++++++++++++++++++++*
A          R TRN_REC
A            TRN_NUMBER     5          TEXT('EMPLOYEE NUMBER')
A            TRN_HOURS      4  1       TEXT('HOURS WORKED')
A            TRN_BONUS      6  2       TEXT('BONUS')

各社員の給与の計算は、「時間数」(TRANSACT ファイルからの) と「社員支給率」 (EMPLOYEE ファイルからの) とを掛けて、それに TRANSACT ファイルからの「ボーナス」を加えることによって行われます。 40 時間を超えて働いた場合には、 通常の率の 1.5 倍が社員に支払われます。

制御仕様書
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
HKeywords++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
H DATEDIT(*DMY/)

今日の日付は、日、月、年の形式で「/」を区切り記号として印刷されます。

ファイル仕様書
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+...
FFilename++IPEASFRlen+LKlen+AIDevice+.Keywords+++++++++++++++++++++++++++
FTRANSACT  IP   E           K DISK
FEMPLOYEE  IF   E           K DISK
FQSYSPRT   O    F   80        PRINTER
ファイル仕様書には次の 3 つのファイルが定義されています。
  • TRANSACT ファイルは入力 1 次ファイルとして定義されて います。 ILE RPG プログラム・サイクルは、このファイルからのレコードの読み取りを制御します。
  • EMPLOYEE ファイルは入力全手順ファイルとして定義されています。 このファイルからのレコードの読み取りは、演算仕様書の命令によって制御されます。
  • QSYSPRT ファイルは出力印刷ファイルとして定義されています。
定義仕様書
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+...
D+Name++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++
D Pay             S              8P 2
D Heading1        C                   'NUMBER  NAME              RATE    H-
D                                     OURS  BONUS    PAY       '
D Heading2        C                   '______  ________________  ______  _-
D                                     ____  _______  __________'
D CalcPay         PR             8P 2
D   Rate                         5P 2 VALUE
D   Hours                       10U 0 VALUE
D   Bonus                        5P 2 VALUE

定義仕様書を使用して、社員の週給を入れる "Pay" という変数と報告書の見出し の印刷に備えての "Heading1" と "Heading2" の 2 つの固定情報を宣言します。

演算仕様書 変更の始まり
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+...
 /free
     chain trn_number emp_rec;  1 
     *IN99 = NOT %found(employee);  2 
     if %found(employee);  3 
        pay = CalcPay (emp_rate: trn_hours: trn_bonus);
     endif;
 /end-free
変更の終わり
演算仕様書のコーディング項目には、以下のものが含まれています。
  1. CHAIN 命令コードを使用することにより、社員ファイル中の同じ社員番号 を持つレコードを見つけるために、 トランザクション・ファイルからの TRN_NUMBER フィールドが使用されます。
  2. 変更の始まり*IN99 には %FOUND の反対が割り当てられます。後の出力仕様書は、標識 99 によって条件設定されます。CHAIN 命令によってレコードが検出されなかった場合、標識 99 には値 *ON を指定する必要があります。変更の終わり
  3. 変更の始まりCHAIN 命令が正常に行われる (つまり、%FOUND が *ON を返す) 場合、その従業員の給料が評価されます。結果は「四捨五入」されて、Pay という変数に保管されます。変更の終わり
出力仕様書
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+...
OFilename++DF..N01N02N03Excnam++++B++A++Sb+Sa+...........................
O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat
OQSYSPRT   H    1P                     2  3
O                                           35 '給与計算表'
O                       *DATE         Y     60
O          H    1P                     2
O                                           60 Heading1
O          H    1P                     2
O                                           60 Heading2
O          D   N1PN99                  2
O                       TRN_NUMBER           5
O                       EMP_NAME            24
O                       EMP_RATE      L     33
O                       TRN_HOURS     L     40
O                       TRN_BONUS     L     49
O                       Pay                 60 '$     0.  '
O          D   N1P 99                  2
O                       TRN_NUMBER           5
O                                           35 '** 社員ファイル上にない **'
O          T    LR
O                                           33 'END OF LISTING'
出力仕様書では、どのフィールドを QSYSPRT 出力に書き出すかを記述します。
  • 明細情報用の見出しと同様に固定情報ストリング「PAYROLL REGISTER (給与計算表)」を含んで いる見出し行は、標識 1P がオンの場合に印刷されます。 標識 1P は、最初のサイクル時に ILE RPG プログラム・サイクルによってオンにされます。
  • 明細行は標識 1P および 99 によって条件付けられます。 明細行は 1P 時には印刷されません。 N99 は、標識 99 がオフである (対応する社員レコードが見付かったことを示 す) 場合にだけ、明細行を印刷することができます。 標識 99 がオンの場合には、明細行の代わりに社員番号と固定情報ストリング 「** NOT ON EMPLOYEE FILE ** (** 社員ファイル上にない **)」が印刷されます。
  • 合計行には、「END OF LISTING (リストの終わり)」という固定情報ストリングが含まれます。 これは最後のプログラム・サイクル時に印刷されます。

サブプロシージャー

サブプロシージャーは、渡されたパラメーターを使用して社員の給与を計算し ます。 結果の値は、RETURN ステートメントを使用して呼び出し元に戻されます。

プロシージャー仕様書はプロシージャーの始めと終わりを指示します。 定義仕様書は、プロシージャーの戻りタイプ、プロシージャーへのパラメーター 、およびローカル変数である Overtime を定義します。
P CalcPay         B
D CalcPay         PI             8P 2
D   Rate                         5P 2 VALUE
D   Hours                       10U 0 VALUE
D   Bonus                        5P 2 VALUE
D Overtime        S              5P 2 INZ(0)

 /free
    // 支払われる超過勤務時間を決定します。
    if Hours > 40;
      Overtime = (Hours - 40) * Rate * 1.5;
      Hours = 40;
    endif;
    // 給与合計を計算し、呼び出し元に戻します。
    return  Rate * Hours + Bonus + Overtime;
 /end-free
P CalcPay         E

ソース・プログラム全体

次の図は、このプログラムで使用されるすべての仕様書を組み合わせます。この図は、このプログラムのソース・ファイルに入力すべきものを示しています。

図 3. 給与計算サンプル・プログラム
 *------------------------------------------------------------------------*
 * 説明: このプログラムは、社員の週給の印刷出力を                         *
 *       作成します。                                                     *
 *------------------------------------------------------------------------*
H DATEDIT(*DMY/)
 *------------------------------------------------------------------------*
 * ファイル定義                                                           *
 *------------------------------------------------------------------------*
FTRANSACT  IP   E           K DISK
FEMPLOYEE  IF   E           K DISK
FQSYSPRT   O    F   80        PRINTER
 *------------------------------------------------------------------------*
 * 変数の宣言                                                             *
 *------------------------------------------------------------------------*
D Pay             S              8P 2
 *------------------------------------------------------------------------*
 * 定数の宣言                                                             *
 *------------------------------------------------------------------------*
D Heading1        C                   'NUMBER  NAME              RATE    H-
D                                     OURS  BONUS    PAY       '
D Heading2        C                   '______  ________________  ______  _-
D                                     ____  _______  __________'
 *------------------------------------------------------------------------*
 * サブプロシージャー CalcPay のためのプロトタイプの定義                  *
 *------------------------------------------------------------------------*
D CalcPay         PR             8P 2
D   Rate                         5P 2 VALUE
D   Hours                       10U 0 VALUE
D   Bonus                        5P 2 VALUE
 *------------------------------------------------------------------------*
 * トランザクション・ファイル (TRANSACT) 内の各レコードごとに、           *
 * 該当する社員が見つかった場合は給与を計算し明細を印刷します。           *
 *------------------------------------------------------------------------*
 /free
    chain trn_number emp_rec;
    if %found(emp_rec);
       pay = CalcPay (emp_rate: trn_hours: trn_bonus);
    endif;
 /end-free
 *------------------------------------------------------------------------*
 * 報告書レイアウト                                                       *
 *  -- 1P がオンであれば見出し行を印刷する                                *
 *  -- レコードが見つかった場合 (標識 99 がオフ) は                       *
 *     給与明細を印刷し、それ以外の場合は例外レコードを印刷する           *
 *  -- LR がオンのときは 'リストの終わり' と印刷する                      *
 *------------------------------------------------------------------------*
OQSYSPRT   H    1P                     2  3
O                                           35 '給与計算表'
O                       *DATE         Y     60
O          H    1P                     2
O                                           60 Heading1
O          H    1P                     2
O                                           60 Heading2
O          D   N1PN99                  2
O                       TRN_NUMBER           5
O                       EMP_NAME            24
O                       EMP_RATE      L     33
O                       TRN_HOURS     L     40
O                       TRN_BONUS     L     49
O                       Pay                 60 '$     0.  '
O          D   N1P 99                  2
O                       TRN_NUMBER           5
O                                           35 '** 社員ファイル上にない **'
O          T    LR
O                                           33 'END OF LISTING'
 *------------------------------------------------------------------------*
 * サブプロシージャー  -- 超過時間給与を計算します。                      *
 *------------------------------------------------------------------------*
P CalcPay         B
D CalcPay         PI             8P 2
D   Rate                         5P 2 VALUE
D   Hours                       10U 0 VALUE
D   Bonus                        5P 2 VALUE
D Overtime        S              5P 2 INZ(0)

 /free
    // 支払われる超過勤務時間を決定します。
    if Hours > 40;
      Overtime = (Hours - 40) * Rate * 1.5;
      Hours = 40;
    endif;
    // 給与合計を計算し、呼び出し元に戻します。
    return(H)  Rate * Hours + Bonus + Overtime;
 /end-free
P CalcPay         E