020-030 帳票系プログラムその１（単純一覧

## 本記事の内容とサンプルコード

本記事では、一番シンプルな構造を持つ「帳票系プログラム」の解説を行う。
IBM i 上に QEOLFF 環境が存在する場合は`/QEOLFF/QRPGLESRC/BPL010@YU1.RPGLE ,BPL010@YU2.RPGLE` を、環境がない場合でもサンプルコードは次のURLより取得、閲覧可能である。

■例で使用するサンプルコード
- [ 品目マスタ一覧（固定 - /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/QPRTSRC/BPL010P.PRTF](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QPRTSRC/BPL010P.PRTF)

---

■印刷イメージ
![030-010-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520639/883ffda8-f156-7ef5-af25-c8476c37b781.png)

## 前提条件

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

- [010-前提条件／環境構築](https://qiita.com/ibm_knowledge_mall/items/0536889104b90990e074)
- [前回の記事）020-仕様書と各CTLについて](https://qiita.com/ibm_knowledge_mall/items/a64bbc4703dc9c5d8d39)

## 参考リンク

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

- [IBM i - ILE RPG 解説書(V7R5)](https://www.ibm.com/docs/ja/i/7.5?topic=rpg-ile-reference)
- [IBM i - DDS 印刷装置ファイル](https://www.ibm.com/docs/ja/i/7.5?topic=dds-printer-files)
- [ＦＦで許可されていない記述集１（ＦＦ - /QEOLFF/QRPGLESRC/@USHIDAY11.RPGLE](https://github.com/IBMCJ-2023-C06/020-FF_RPG_samples/blob/main/QRPGLESRC/%40USHIDAY11.RPGLE)

## ステートメント順序の柔軟性

固定形式 `BPL010@YU1.RPGLE` と自由形式 `BPL010@YU2.RPGLE` を比較すると、次の様にステートメント（旧仕様書）順位にある程度柔軟性があることがわかる。
固定形式では、仕様書の順位に制約が存在したが、自由形式では関連ステートメントのそばに異なるステートメントの記述を行う事も可能となっている。

以下の例では、変数 `W#FG_OF` は印刷装置 `BPL010P` の `OFLIND` オーバーフロー標識（帳票のページあふれによる改ページを判定する標識）として定義されている。
固定形式では、`F仕様書` と `D仕様書` でソースコードが離れた場合、見通しが悪かったが、自由形式では `DCL-F` の直下に `DCL-S` で宣言することも可能となっている。このためプログラムでの見通しがし易い。もちろん従来どおり離れた位置で宣言することも可能である。
また、自由形式では変数型の `N→IND` で表される。

```RPGLE:固定形式の例
     F*印刷装置
     FBPL010P   O    E             PRINTER OFLIND(W#FG_OF )
～～～中略～～～
     D W#FG_OF         S               N
```

```RPGLE:BPL010@YU2.RPGLE
DCL-F    BPL010P       PRINTER  OFLIND(W#FG_OF              )                ;
  DCL-S    W#FG_OF       IND                                                   ;
```

## 自由形式では許可されていない KLIST

前回の記事でも言及したが、自由形式では、固定形式で可能であった、幾つかの記述や命令が使用できない制約が存在する。RPGではよく利用される **「KLIST」** もその一つだ。自由形式ではどの様になるか、サンプルコードを抜粋して見ていく。

```RPGLE:BPL010@YU1.RPGLE
     C*-********************************************************************
     C*-* ＰＬＩＳＴ／ＫＬＩＳＴ                                        **
     C*-********************************************************************
     C     HINMSKEY1     KLIST
     C                   KFLD                    K@HNBANG                       品目番号
     C     *LIKE         DEFINE    HNBANG        K@HNBANG
```

```RPGLE:BPL010@YU2.RPGLE
//   D*-********************************************************************
//   D*-* ＫＬＩＳＴ                                                    **
//   D*-********************************************************************
//品目マスタ
DCL-DS   HINMSKEY1     LIKEREC(HINMSR     : *KEY            ) INZ            ;
```

`KLITS` 命令は固定形式では `C仕様書` で記述されていた、これに変わる代替手段の一つは、`DCL-S` ステートメントにてデータ構造を宣言することで解決出来る。

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

- `C仕様書KLIST` の代替手段として `DCL-DS` データ構造 `HINMSKEY1` を `LIKEREC(HINMSR:*KEY)` 品目マスタが保持するレコード様式のキーと同様の構造で宣言

`LIKEREC` キーワードは、`DCL-F` ステートメントで宣言されているファイルのレコード様式より、`*KEY` オプションを使用して、`KLIST` と同等のデータ構造を定義する事が出来る。宣言された変数 `HINMSKEY1` は、自動的に修飾され `HINMSKEY1.HNBANG` の様に使用する事が可能だ。複合キーの場合は、修飾されるカラム名が `HOGEKEY1.COL1`、`HOGEKEY1.COL2` の様になる。

```PF:QEOL/QEOLDBF/HINMSP.PF
A* 品目マスター　物理ファイル (HINMSP)
A*       ↓LIKEREC キーワードで使用されるレコード様式名
A          R HINMSR
A            HNBANG         5          COLHDG(' 品目 ' ' 番号 ')
～～～中略～～～
A*
A*       ↓*KEY オプションでデータ構造化されるキー
A          K HNBANG
```

```RPGLE:BPL010@YU2.RPGLE
//開始キー位置づけ
HINMSKEY1.HNBANG       = *LOVAL        ;      //品目番号
SETLL %KDS(HINMSKEY1   ) HINMSR        ;
```

また、`%KDS` 関数（接頭に%が付与されたものはRPGの組み込み関数）は、従来 `KLIST` で操作が行えた `SETLL,SETGT,READE,CHAIN` 命令に対して使用する。
`KLIST` 命令代替として **「データ構造をKLIST化する」** 関数だと言える。

■参考リンク
- [LIKEREC(intrecname{:extract-types})](https://www.ibm.com/docs/ja/i/7.5?topic=keywords-likerecintrecnameextract-types)
- [%KDS (データ構造の検索引数)](https://www.ibm.com/docs/ja/i/7.5?topic=functions-kds-search-arguments-in-data-structure)

## 演算ステートメントの評価式

RPG-III(RPG400含む) から RPG-IV（固定形式） にバージョンアップされた際に、幾つかの命令 `MOVE,MOVEL,Z-ADD,ADD,Z-SUB,SUB,SETON,SETOFF,etc...` は `EVAL`、`EVAL-R` 式の評価命令で置き換える事が可能となっている。`EVAL`系命令に統一する事により、変数型を意識しない命令セットになったと言える。
更に自由形式では、`EVAL` 命令を省略し記述する事が可能となり、この作用で他の一般的なコンピュータ言語の類似した文法の様に見ることが可能となっている。

■参考リンク
- [EVAL (式の評価)](https://www.ibm.com/docs/ja/i/7.5?topic=codes-eval-evaluate-expression)
- [EVALR (式の評価、右寄せ)](https://www.ibm.com/docs/ja/i/7.5?topic=codes-evalr-evaluate-expression-right-adjust)

■固定形式
```RPGLE:BPL010@YU1.RPGLE
C*-***************************************************************
     C*-* @INZ        初期処理                                     **
     C*-***************************************************************
     C     @INZ          BEGSR
～～～中略～～～
     C*オーバーフロー標識オン
     C                   SETON                                        80
     C*
     C*印刷件数
     C                   Z-ADD     *ZERO         W#CNTP            9 0          印刷件数
     C*
～～～中略～～～     
     C*-***************************************************************
     C*-* @PITEM1     印刷処理（明細                               **
     C*-***************************************************************
     C     @PITEM1       BEGSR
     C*
～～～中略～～～          
     C                   MOVEL(P)  HNBANG        PI1HNBANG                      品目番号
～～～中略～～～               
     C                   ADD       1             W#CNTP                         印刷件数
```

■自由形式
```RPGLE:BPL010@YU2.RPGLE
//   C*-***************************************************************
//   C*-* @INZ        初期処理                                     **
//   C*-***************************************************************
BEGSR @INZ                                  ;
～～～中略～～～
//変数の初期化
     //*IN(80) = *ON                                   ;    //オーバーフロー標識
     W#FG_OF = *ON                                   ;    //オーバーフロー標識
     W#CNTP  = *ZERO                                 ;    //印刷件数
～～～中略～～～
//   C*-***************************************************************
//   C*-* @PITEM1     印刷処理（明細                               **
//   C*-***************************************************************
BEGSR @PITEM1                               ;
～～～中略～～～
     PI1HNBANG  =  HNBANG                            ; //品目番号
～～～中略～～～
     W#CNTP  += 1                                    ;    //印刷件数
```

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

- ①変数（プログラム内部 `W#FG_OF` に `*ON` を代入している
- ②変数（プログラム内部 `W#CNTP` に `*ZERO` を代入している
- ③変数（印刷装置 `PI1HNBANG` に 変数（データベース `HNBANG` を代入している
- ④変数（プログラム内部 `W#CNTP` に `1` を加算している

①ではこれまで `SETON` `SETOFF` 命令を用いていた記述を一般的な代入の評価式として記述する事が可能となっている
②ではこれまで `Z-ADD` `Z-SUB` 命令を用いていた記述を一般的な代入の評価式として記述する事が可能となっている
③ではこれまで `MOVEL` `MOVE` 命令を用いていた記述を一般的な代入の評価式として記述する事が可能となっている
④ではこれまで `ADD` `SUB` 命令を用いていた記述を一般的な代入の評価式として記述する事が可能となっている。`W#CNTP += 1` は `W#CNTP = W#CNTP + 1`と同意である。（減算の場合は`-=`）

前述の通り、印刷装置、データベースなど装置を操作する命令（`READ` `WRITE` `CLEAR`）については変更はないが、変数への値代入系の命令については、自由形式においてかなりの部分で省略し評価式への統一が可能となっている。

## ループ操作

自由形式では、`GOTO,TAG` 命令が使用不可となっている、構造化プログラミングの観点から、固定形式時代でも意図的に使用しない事はあるが、全てのプログラムがそうなっているは言えない。まだまだ、ループ操作を行う際に `GOTO,TAG` や、永久ループをループ操作を行う際に `DO        *HIVAL` などの記述で実現されている事もままある。
自由形式では、ループ操作をどう行うのか見ていく。

■固定形式
```RPGLE:BPL010@YU1.RPGLE
     C                   DO        *HIVAL
     C*
     C*読取り
     C                   READ      HINMSR
     C                   IF        %EOF
     C                   LEAVE
     C                   ENDIF
     C*印刷（明細
     C                   EXSR      @PITEM1
     C*
     C                   ENDDO

```

■自由形式
```RPGLE:BPL010@YU2.RPGLE
DOW  1 = 1                             ;
  READ   HINMSR                          ;
  IF        %EOF                         ;
    LEAVE                                  ;
  ENDIF                                  ;
  //印刷（明細
  EXSR      @PITEM1                      ;
ENDDO                                  ;
```

固定形式では `DO        *HIVAL` が使用されているが `DO` 命令も自由形式では使用不可となっている。代替となるのが `DOW` `DOU` `FOR` `LEAVE` 命令となる。ループ操作の幾つかのパターンを以下に示す。

1. 意図的に永久ループを作る① `DOW  1 = 1;` （`DO        *HIVAL`の代替）
2. 意図的に永久ループを作る② `DOW  *ON;` （`DO        *HIVAL`の代替）※OSバージョンによっては使用不可
3. 条件の終わりを判定する① `DOW  NOT %EOF(HINMSP)`
4. 条件の終わりを判定する② `DOU  %EOF(HINMSP)`

■参考リンク
- [GOTO (演算命令のスキップ) 不可：自由形式](https://www.ibm.com/docs/ja/i/7.5?topic=codes-goto-go)
- [DO (命令グループの開始) 不可：自由形式](https://www.ibm.com/docs/ja/i/7.5?topic=codes-do-do)
- [DOW (条件が真の間繰り返し)](https://www.ibm.com/docs/ja/i/7.5?topic=codes-dow-do-while)
- [DOU (条件が真になるまでの繰り返し)](https://www.ibm.com/docs/ja/i/7.5?topic=codes-dou-do-until)
- [FOR (For)](https://www.ibm.com/docs/ja/i/7.5?topic=codes-)
- [LEAVE (Do/For グループからの抜け出し)](https://www.ibm.com/docs/ja/i/7.5?topic=codes-leave-leave-dofor-group)

## 利用頻度の高い組み込み関数

ここでは幾つかの利用頻度の高い組み込み関数が使用されているので、これについて解説する。

■固定形式
```RPGLE:BPL010@YU1.RPGLE
C*-***************************************************************
     C*-* @INZ        初期処理                                     **
     C*-***************************************************************
     C     @INZ          BEGSR
     C*
     C*システム日付
     C                   TIME                    WTIME            14 0
     C                   MOVEL     WTIME         WTIME6            6 0
     C                   MOVE      WTIME         WDATE8            8 0
```

■自由形式
```RPGLE:BPL010@YU2.RPGLE
//   C*-***************************************************************
//   C*-* @INZ        初期処理                                     **
//   C*-***************************************************************
BEGSR @INZ                                  ;

//システム日付
     WTIMESTAMP = %TIMESTAMP()                       ;
     WDATE8     = %DEC(%DATE(WTIMESTAMP) : *ISO )    ;
     WTIME6     = %DEC(%TIME(WTIMESTAMP) : *HMS )    ;
```

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

- 変数 `WTIMESTAMP` に `%TIMESTAMP` 関数を使用してシステム日付＆時刻を取得している
- 変数 `WDATE8` に `%DATE(WTIMESTAMP)` 関数を使用してタイムスタンプより日付部分を取得、更に `%DEC(～中略～ : *ISO )` 数値8桁の `YYYYMMDD` 形式に変換している
- 変数 `WTIME6` に `%TIME(WTIMESTAMP)` 関数を使用してタイムスタンプより時刻部分を取得、更に `%DEC(～中略～ : *HMS )` 数値6桁の `HHMMSS` 形式に変換している

`%TIMESTAMP`、`%DATE`、`%TIME`、`%DEC` これら関数は、日付、時刻操作では利用頻度の高い関数であり、データベースの更新時にタイムスタンプを設定する際などもよく利用されるので学習しておくと良い。

■参考リンク
- [%TIMESTAMP (タイム・スタンプへの変換)](https://www.ibm.com/docs/ja/i/7.5?topic=functions-timestamp-convert-timestamp)
- [%DATE (日付への変換)](https://www.ibm.com/docs/ja/i/7.5?topic=functions-date-convert-date#bbdate)
- [%TIME (時刻への変換)](https://www.ibm.com/docs/ja/i/7.5?topic=functions-time-convert-time#bbtime)
- [%DEC (パック 10 進数への変換)](https://www.ibm.com/docs/ja/i/7.5?topic=functions-dec-convert-packed-decimal-format#bbdec)

## 終わりに

以上で **帳票系プログラムその１（単純一覧*** の解説を終了する。サンプルコードを眺めるだけでなく、自身でキーワードを変更したり、オプションを変更したり、また別の組み込み関数を使うなどしてみると、よりいっそう理解が深まるだろう。


## 編集履歴

- 作成日：IBMCJ-2023-C06 (CSC)Y.USHIDA 2023.08.20 15:00 [新規投稿]
- 更新日：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をご覧ください。