020-020 仕様書と各CTLについて

## サンプルコード
■例で使用する固定形式（従来のRPG）、自由形式（FF-RPG）のサンプルコード
- [ 品目マスタ一覧（固定 - /QEOLFF/QRPGLESRC/BPL010@YU1.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/BPL010%40YU1.RPGLE)
- [ 品目マスタ一覧（ＦＦ - /QEOLFF/QRPGLESRC/BPL010@YU2.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/BPL010%40YU2.RPGLE)
- [ 地区別受注一覧表（固定 - /QEOLFF/QRPGLESRC/BPL030@YU1.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/BPL030%40YU1.RPGLE)
- [ 地区別受注一覧表（ＦＦ - /QEOLFF/QRPGLESRC/BPL030@YU2.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/BPL030%40YU2.RPGLE)
- [ ＤＳサンプル１（固定 - /QEOLFF/QRPGLESRC/DCLDS1@YU1.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/DCLDS1%40YU1.RPGLE)
- [ ＤＳサンプル２（ＦＦ - /QEOLFF/QRPGLESRC/DCLDS1@YU2.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/DCLDS1%40YU2.RPGLE)

## 前提条件

以下のリンクより、本コンテンツの **FF-RPG** サンプルコードを閲覧、実行する環境を整備する

- [010-前提条件／環境構築](https://qiita.com/ibm_knowledge_mall/items/0536889104b90990e074)

## 参考リンク

以下、リンクは OS バージョンが **V7R5** のリンク先となっているが、サイト左の **「バージョンの変更」** より、自身の環境に合ったバージョンへ変更可能。

- [IBM i - ILE RPG 解説書(V7R5)](https://www.ibm.com/docs/ja/i/7.5?topic=rpg-ile-reference)
- [IBM i - RPG IV 仕様書タイプ](https://www.ibm.com/docs/ja/i/7.5?topic=specifications-rpg-iv-specification-types)
- [IBM i - 自由形式ステートメント](https://www.ibm.com/docs/ja/i/7.5?topic=specifications-free-form-statements)

## 仕様書とステートメント

まず、 **FF-RPG** を学習するにあたり、固定形式（従来のRPG）、自由形式（FF-RPG）においてソースコードの構造とその呼称に幾つかの変更点がある。  
従来の固定形式では、 **「仕様書」** と呼ばれる概念で、各仕様書が言語構造を表していた。代表的な幾つかの仕様書は以下の通り。

- H 制御仕様書
  - コンパイラーへの指示
  - プログラム全体の設定（日付書式 etc...）
- F ファイル仕様書
  - データベース（物理ファイル、論理ファイル）宣言
  - 画面ファイル宣言
  - 帳票ファイル宣言
- D 定義仕様書
  - 変数、定数、配列、データ構造
- C 演算仕様書
  - 所謂プログラム処理コードを記述

そして、これらの記述の **順序は「H→F→D→C」** と規則が決められており、この順序が守られていない場合は、コンパイル・エラーとなる。
更にRPGは、これらの仕様書概念の外側に **メイン・プロシージャ** 、 **サブ・プロシージャ** と呼ばれる、セクション概念を持つが、本コンテンツでは、割愛し主に **メイン・プロシージャ** による単一セクションについて言及する。

自由形式ではこれら **仕様書** が **ステートメント** と呼ばれる形に変更されており、次のように対比できる。
以下の完全自由形式を使用する場合には、**「ソースの最初の行に ** FREEが含まれている」** 必要がある。
また、RPGコンパイラは、命令やステートメントに関する記述に関して、大文字／小文字を区別しないため、本コンテンツの記載では極力大文字側の記述に統一している。

|固定形式|自由形式|備考|
|---|---|---|
|H仕様書|CTL-OPT||
|F仕様書|DCL-F||
|D仕様書（定数|DCL-C||
|D仕様書（独立変数 S|DCL-S||
|D仕様書（データ構造|DCL-DS ～ END-DS||
|C仕様書|宣言部は特になし|/FREE を記述すると部分的に自由形式を使用可能|

次に前回のサンプルコードにある `/QEOLFF/QRPGLESRC/BPL***.RPGLE` を題材を例に主な仕様書の詳細について述べていく。
これらサンプルコードに掲載されているプログラムIDは、元となる `/QEOL/QRPGLESRC/BPL***.RPGLE` と一致しており、オリジナルの固定形式がどうなっているかを確認する場合は、そちらを参照すると良い。（※但し、本コンテンツは、一部の画面ファイルや帳票ファイルにオリジナルの要素を含んでいる）

■例で使用するサンプルコード(再掲)
- [ 品目マスタ一覧（固定 - /QEOLFF/QRPGLESRC/BPL010@YU1.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/BPL010%40YU1.RPGLE)
- [ 品目マスタ一覧（ＦＦ - /QEOLFF/QRPGLESRC/BPL010@YU2.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/BPL010%40YU2.RPGLE)
- [ 地区別受注一覧表（固定 - /QEOLFF/QRPGLESRC/BPL030@YU1.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/BPL030%40YU1.RPGLE)
- [ 地区別受注一覧表（ＦＦ - /QEOLFF/QRPGLESRC/BPL030@YU2.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/BPL030%40YU2.RPGLE)
- [ ＤＳサンプル１（固定 - /QEOLFF/QRPGLESRC/DCLDS1@YU1.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/DCLDS1%40YU1.RPGLE)
- [ ＤＳサンプル２（ＦＦ - /QEOLFF/QRPGLESRC/DCLDS1@YU2.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/DCLDS1%40YU2.RPGLE)

## 制御ステートメント（旧H仕様書）

固定形式と自由形式の比較は以下の通りなっている。

```RPGLE:BPL010@YU1.RPGLE
     H*-*******************************************************************
     H*-*Ｈ仕様書                                                      **
     H*-*******************************************************************
     H DATEDIT(*YMD)
     H DECEDIT('0.')
     H COPYRIGHT('COPYRIGHT(C) CHUBU SYSTEM CO.,LTD. ALL RIGHTS RESERVED')
```

```RPGLE:BPL010@YU2.RPGLE
**FREE
CTL-OPT
       DATEDIT(*YMD)
       DECEDIT('0.')
       COPYRIGHT('COPYRIGHT(C) CHUBU SYSTEM CO.,LTD. ALL RIGHTS RESERVED')
;
```

上記ではコード例では次の事を行っている

- `DATEDIT(*YMD)` タイムスタンプ等の日付書式を「*YMD」に設定
- `DECEDIT('0.')` 数値ゼロの編集書式を「0.」に設定
- `COPYRIGHT(～'` オブジェクト内の著作権情報を設定（※ここに記載されているのはあくまで記述例であり、本コンテンツの実際の著作権とは無関係である）

これは、全般的に言えることだが、自由形式において、ステートメントの終了を表すには **「;（セミコロン）」** を必要とする。
そして固定形式で意識していた、桁位置という概念は存在せず、ネストや改行はルールに従えば任意で行う事が出来る。また、コメント行に関しては **「//（スラッシュ×２）」** で表現される。

筆者の個人的な見解としては、H仕様書と制御ステートメントにおいて、自由形式による大きな違いはなく、**「Hを外し従来どおりの記述を」** 行うだけである。
留意点としては、実際にコンパイルした結果、制御ステートメントはソース・コードの先頭に記述する事が必要と考えられる。

## ファイルステートメント（旧F仕様書）

固定形式と自由形式の比較は以下の通りなっている。

```RPGLE:BPL010@YU1.RPGLE
     F*-*******************************************************************
     F*-*Ｆ仕様書                                                      **
     F*-*******************************************************************
     F*品目マスタ
     FHINMSP    IF   E           K DISK
```

```RPGLE:BPL010@YU2.RPGLE
DCL-F    HINMSP        KEYED    USAGE(*INPUT                )                ;
```

上記ではコード例では次の事を行っている

- `HINMSP` 品目マスタを全手順かつ `KEYED` キー付きの `USAGE(*INPUT)`入力ファイルとして宣言

比較すると `DCL-F` でステートメント宣言が開始され、各オプションが宣言的な言葉で次の様に置き換えられている。

- I → USAGE(*INPUT)
- K → KEYED

また、幾つかの制約はあるが、宣言は必ず制御ステートメントの次である必要はない。

■幾つかの制約
1. メインルーチンの演算ステートメントが開始される前に宣言
2. LIKE系で変数等が参照される場合は、それより上位で宣言

また、**SQLRPGLE** で作成する場合はデータベース参照部分において、ファイル宣言を不要とする事も出来る。但し、帳票ファイル、画面ファイルなど IBM i 固有部分のファイル宣言が残る事は覚えておきたい。

## 定義ステートメント（旧D仕様書）

### 独立変数（DCL-S）

固定形式と自由形式の比較は以下の通りなっている。

```RPGLE:BPL030@YU1.RPGLE
     D*-********************************************************************
     D*-* テーブル／配列定義                                            **
     D*-********************************************************************
     D*地区名称
     D   IX            S              1S 0
     D   TIKCOD        S              2A   DIM(05) PERRCD(01) CTDATA
     D   TIKNAM        S              8A   DIM(05) ALT(TIKCOD)
```

```RPGLE:BPL030@YU2.RPGLE
//   D*-********************************************************************
//   D*-* テーブル／配列定義                                            **
//   D*-********************************************************************
//地区名称
DCL-S  IX            ZONED(1:0)                               ;  //指標
DCL-S  TIKCOD        CHAR(002) DIM(05) PERRCD(01) CTDATA      ;  //地区コード
DCL-S  TIKNAM        CHAR(008) DIM(05) ALT(TIKCOD)            ;  //地区名称
//～～～中略～～～
** TIKCOD/TIKNAM 地区コード／地区名
01北海道
02東北
03北陸
04関東
05関西
```

上記ではコード例では次の事を行っている

- 独立変数 `IX` を `ZONED(1:0)` ゾーン10進数型を整数1桁、小数0桁で宣言
- 独立変数 `TIKCOD` を `CHAR(002)` 文字列型を整数2桁、`DIM(05)` 要素数5個の配列、`PERRCD(01) CTDATA` コンパイル時データ＆レコード数１で宣言
- 独立変数 `TIKNAM` を `CHAR(008)` 文字列型を整数8桁、`DIM(05)` 要素数5個の配列、`ALT(TIKCOD)` **TIKCOD変数** を関連配列として宣言

比較すると `DCL-S` でステートメント宣言が開始され、各オプションが宣言的な言葉で次の様に置き換えられている。

- S → DCL-S
- 1S 0 → ZONED(1:0)
- 2A → CHAR(002) or CHAR(2)

`DIM(05) PERRCD(01) CTDATA`などのキーワード記述には変更がないためそのまま従来通りとなる。

### データ構造（DCL-DS）

固定形式と自由形式の比較は以下の通りなっている。

```RPGLE:DCLDS1@YU1.RPGLE
     D*-----------------------------------
     D*プログラム状況・データ構造
     D*-----------------------------------
     D                SDS
     D S#PROC                  1     10A                                        プログラム名
     D S#STS                  11     15S 0                                      状況コード
     D S#JOB                 244    253A                                        ジョブ名
     D S#USER                254    263A                                        ユーザー名
     D S#JNBR                264    269S 0                                      ジョブ№
     D*
     D*-----------------------------------
     D*ローカル・データ域
     D*-----------------------------------
     D                UDS                  DTAARA(*LDA)
     D L#DATE                         8S 0                                      処理日付
     D L#EMNO                         5A                                        社員№
     D L#OUTQ1                       10A                                        ＯＵＴＱ１
     D L#OUTQ2                       10A                                        ＯＵＴＱ２
     D*
     D*-----------------------------------
     D*任意のデータ構造
     D*-----------------------------------
     D                 DS
     D D1SYSYMD                1      8S 0                                      システム日付
     D  D1SYSY                 1      4S 0                                      システム年
     D  D1SYSM                 5      6S 0                                      システム月
     D  D1SYSD                 7      8S 0                                      システム日
     D*
     D                 DS
     D D2SYSHMS                       6S 0                                      システム時刻
     D  D2SYSH                        2S 0       OVERLAY(D2SYSHMS: 1    )       システム時
     D  D2SYSM                        2S 0       OVERLAY(D2SYSHMS: 3    )       システム分
     D  D2SYSS                        2S 0       OVERLAY(D2SYSHMS: 5    )       システム秒
```

```RPGLE:DCLDS1@YU2.RPGLE
//   D*-----------------------------------
//   D*プログラム状況・データ構造
//   D*-----------------------------------
DCL-DS *N PSDS;
       S#PROC              CHAR(10)                      ;                    //プログラム名
       S#STS               ZONED(5:0)                    ;                    //状況コード
       S#JOB               CHAR(10)     POS(244)         ;                    //ジョブ名
       S#USER              CHAR(10)     POS(254)         ;                    //ユーザー名
       S#JNBR              ZONED(6:0)   POS(264)         ;                    //ジョブ№
END-DS;
//   D*-----------------------------------
//   D*ローカル・データ域
//   D*-----------------------------------
DCL-DS *N DTAARA(*AUTO : *USRCTL);
       L#DATE              ZONED(8:0)                    ;                    //処理日付
       L#EMNO              CHAR(5)                       ;                    //社員№
       L#OUTQ1             CHAR(10)                      ;                    //ＯＵＴＱ１
       L#OUTQ2             CHAR(10)                      ;                    //ＯＵＴＱ２
END-DS;
//   D*-----------------------------------
//   D*任意のデータ構造
//   D*-----------------------------------
DCL-DS *N;
       D1SYSYMD            ZONED(8:0)                    ;                    //システム日付
        D1SYSY             ZONED(4:0)   POS(1)           ;                    //システム年
        D1SYSM             ZONED(2:0)   POS(5)           ;                    //システム月
        D1SYSD             ZONED(2:0)   POS(7)           ;                    //システム日
END-DS;

DCL-DS *N;
       D2SYSHMS            ZONED(6:0)                             ;           //システム時刻
        D2SYSH             ZONED(2:0)   OVERLAY(D2SYSHMS :1    )  ;           //システム時
        D2SYSM             ZONED(2:0)   OVERLAY(D2SYSHMS :3    )  ;           //システム分
        D2SYSS             ZONED(2:0)   OVERLAY(D2SYSHMS :5    )  ;           //システム秒
END-DS;
```

上記ではコード例では次の事を行っている

- 従来の`SDS`の代替表現。**プログラム状況・データ構造** `*N PSDS` を宣言し、取得可能な情報を各種変数に割当。取得可能な値の詳細→「[プログラム状況データ構造](https://www.ibm.com/docs/ja/i/7.5?topic=exceptionerrors-program-status-data-structure#psdsdt9)」
- 従来の`UDS`の代替表現。**ローカル・データ域** `*N DTAARA(*AUTO : *USRCTL)` を宣言し、LDAより取得可能な情報を各種変数に割当
- 従来の`DS宣言 From～To`の代替表現。プログラム任意の **名前なしデータ構造** `*N` を宣言し、各種変数に位置指定で割当
- プログラム任意の **名前なしデータ構造** `*N` を宣言し、各種変数にOVERLAY キーワードで割当

比較すると `DCL-DS` でステートメントの開始、 `END-DS` でステートメントの終了が宣言されている。従来の固定形式では、次のD仕様書の`DS` 、`S`や、C仕様書の開始までが暗黙的に、`DS` の終了とみなされ分かりづらかった点が改善され、データ構造の範囲においてコードの可読性が良くなっている。
その他、変数の定義に関しては `DCL-S` の独立変数と同様となっている。また、従来データ構造において、`From～To` の桁位置は、`POS(開始位置)` で割当が可能となっている。
固定形式時代から利用可能なキーワード記述 `OVERLAY` を用いた割当も従来通り使用可能となっている。

- DS → `DCL-S` ～ `END-DS`
- SDS → `*N PSDS`
- UDS → `*N DTAARA(*AUTO : *USRCTL)`
- From To 桁位置の割当 → `POS(開始位置)`
- `OVERLAY` 等はそのまま利用可能

## 演算ステートメント（旧C仕様書）

固定形式と自由形式の比較は以下の通りなっている。

```RPGLE:BPL010@YU1.RPGLE
     C*-********************************************************************
     C*-* ＰＬＩＳＴ／ＫＬＩＳＴ                                        **
     C*-********************************************************************
     C     HINMSKEY1     KLIST
     C                   KFLD                    K@HNBANG                       品目番号
     C     *LIKE         DEFINE    HNBANG        K@HNBANG
     C*-********************************************************************
     C*-* メインルーチン                                                **
     C*-********************************************************************
     C*初期処理
     C                   EXSR      @INZ
     C*
```

```RPGLE:BPL010@YU2.RPGLE
//   D*-********************************************************************
//   D*-* ＫＬＩＳＴ                                                    **
//   D*-********************************************************************
//②品目マスタ
DCL-DS   HINMSKEY1     LIKEREC(HINMSR     : *KEY            ) INZ            ;
//～～～中略～～～
//   C*-********************************************************************
//   C*-* メインルーチン                                                **
//   C*-********************************************************************

//①初期処理
EXSR      @INZ                         ;

```

上記ではコード例では次の事を行っている

- ① `EXSR @INZ;` サブルーチンを実行
- ② `C仕様書KLIST` の代替手段として `DCL-DS` データ構造 `HINMSKEY1` を `LIKEREC(HINMSR:*KEY)` 品目マスタが保持するレコード様式のキーと同様の構造で宣言

比較すると C仕様書の`C` がなくなり、記述方法として **①** と **②** のケースに分ける事が出来る。

**①** のケースは単純に、`C` がなくなり固定桁数の制約がなくなる記述パターンであり、従来どおりの記述と相違ないため特に問題とはならない。
問題となるのは、**②** のケースで、自由形式では許可されておらず、何らかしたの書き換えや新たな記述方式の学習が必要となる。
本コンテンツでは、**「固定形式において利用頻度が高く、自由形式にて許可されていない記述（/QEOLFF/QRPGLESRC/@USHIDAY11.RPGLE）」** に関して、対比用のサンプルコードを成果物として作成した。学習を進める上で、こちらを参考資料として活用していくと良いだろう。

- [ＦＦで許可されていない記述集１（ＦＦ - /QEOLFF/QRPGLESRC/@USHIDAY11.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/%40USHIDAY11.RPGLE)


## 編集履歴

- 作成日：IBMCJ-2023-C06 (CSC)Y.USHIDA 2023.08.20 12:14 [新規投稿]
- 更新日：IBMCJ-2023-C06 (___)_.______ 20__.__.__ __:__ []

## 資料に関する注意書き

本資料の著作権は、日本アイ・ビー・エム株式会社（IBM Corporationを含み、以下、IBMといいます。）に帰属します。
ワークショップ、セッション、および資料は、IBMまたはセッション発表者によって準備され、それぞれ独自の見解を反映したものです。それらは情報提供の目的のみで提供されており、いかなる参加者に対しても法律的またはその他の指導や助言を意図したものではなく、またそのような結果を生むものでもありません。本資料に含まれている情報については、完全性と正確性を期するよう努力しましたが、「現状のまま」提供され、明示または暗示にかかわらずいかなる保証も伴わないものとします。本資料またはその他の資料の使用によって、あるいはその他の関連によって、いかなる損害が生じた場合も、IBMまたはセッション発表者は責任を負わないものとします。 本資料に含まれている内容は、IBMまたはそのサプライヤーやライセンス交付者からいかなる保証または表明を引きだすことを意図したものでも、IBMソフトウェアの使用を規定する適用ライセンス契約の条項を変更することを意図したものでもなく、またそのような結果を生むものでもありません。

本資料でIBM製品、プログラム、またはサービスに言及していても、IBMが営業活動を行っているすべての国でそれらが使用可能であることを暗示するものではありません。本資料で言及している製品リリース日付や製品機能は、市場機会またはその他の要因に基づいてIBM独自の決定権をもっていつでも変更できるものとし、いかなる方法においても将来の製品または機能が使用可能になると確約することを意図したものではありません。本資料に含まれている内容は、参加者が開始する活動によって特定の販売、売上高の向上、またはその他の結果が生じると述べる、または暗示することを意図したものでも、またそのような結果を生むものでもありません。 パフォーマンスは、管理された環境において標準的なIBMベンチマークを使用した測定と予測に基づいています。ユーザーが経験する実際のスループットやパフォーマンスは、ユーザーのジョブ・ストリームにおけるマルチプログラミングの量、入出力構成、ストレージ構成、および処理されるワークロードなどの考慮事項を含む、数多くの要因に応じて変化します。したがって、個々のユーザーがここで述べられているものと同様の結果を得られると確約するものではありません。

記述されているすべてのお客様事例は、それらのお客様がどのようにIBM製品を使用したか、またそれらのお客様が達成した結果の実例として示されたものです。実際の環境コストおよびパフォーマンス特性は、お客様ごとに異なる場合があります。

IBM、IBM ロゴは、米国やその他の国におけるInternational Business Machines Corporationの商標または登録商標です。他の製品名およびサービス名等は、それぞれIBMまたは各社の商標である場合があります。現時点での IBM の商標リストについては、ibm.com/trademarkをご覧ください。