ここに掲げるフローは、なるべく簡略にしたRPGサイクルです。え?ごちゃごちゃしている?大丈夫ゆっくり見ていきましょう。ここが頭に入れば、RPGサイクルはもう、あなたのものです。大きなポイントは、ステップ7で、このサイクル内でレコードを読みとっている事です。そこを「おへそ」に全体を見て下さい。なお、このフローは、通常のRPGサイクルから、オーバーフローやエラー処理をはずして、重要なステップのみ残したものです。
1 |
開始 |
2 |
3 プログラムが初期設定されます。RPG/400言語によって、データ構造とサブフィールドの初期設定、外部標識(U1-
U8)およびユーザー日付フィールド(UDATE、UYEAR、UMONTH、UDAY)のセットアップ、ファイルのオープン、すべてのデータ域データ構造、配列、およびテーブルのロード、*ENTRY
PLISTのPARMSステートメントの結果フィールドの演算項目1への転送、初期設定サブルーチン
*INZSRの実行、および RESET命令のための構造と変数の記憶が行われます。 |
3 |
見出しおよび明細行(出力仕様書の 15 桁目の H または
D
によって識別される)を、最初のレコードが読み取られる前に書き出します。見出し行および明細行は常に同時に処理されます。条件付け標識の指定がある場合には、標識の設定値が正しくなければなりません。ページ・オーバーフロー・ルーチンが指定してあってオーバーフロー標識がオンの場合には、該当のオーバーフロー行が書き出されます。ファイル変換が指定されている場合には、見出し行、明細行、およびオーバーフロー出力についてこれが実行されます。ENDSR
命令の演算項目2に入っているフィールド名またはリテラルの値が*DETLの場合には、このステップはプログラム内の戻り点になります。 |
4 |
レコード識別標識、1P(1ページ目)標識、および制御レベル(
L1 〜 L9)標識が、すべてオフにセットされます。オーバーフロー標識(
OA 〜 OG、OV)は前の明細演算または明細出力でオンにセットされたのでなければ、すべてオフにセットされます。その他のオンの標識はオンのまま残ります。 |
5 |
LR (最終レコード)標識がオンか否かが判別されます。これがオンの場合には、プログラムはステップ
6 から続行され、オンでない場合には、プログラムはステップ 7
に分岐します。 |
6 |
RPG/400言語は、該当の制御レベル(L1 - L9)
標識をオンにセットして、ステップ 11 へ分岐します。 |
7 |
最初のプログラム・サイクルでは、RPG/400言語がプログラム中のプライマリー・ファイルおよび各セカンダリー・ファイルから最初のレコードを読み取ります。これ以外のプログラム・サイクルでは、RPG/400言語が、処理された最後のファイルからレコードを読み取ります。レコード・アドレス(RA)ファイルによって処理されるファイルの場合には、検索するレコードはレコード・アドレス・ファイル内のデータによって定義されます。最後に処理されたレコードで先読みフィールドが指定されている場合には、そのレコードがすでに記憶域に入っている可能性があるため、この時点では、読取りが行われない場合もあります。 |
8 |
RPG/400言語によって、処理用に選択されたレコードのレコード識別標識がオンにセットされます。 |
9 |
処理用に選択したレコードによって制御の切れ目が起こったか否かが判別されます。処理中のレコードの制御フィールドの値が最後に処理したレコードの制御フィールドの値と異なる場合に、制御の切れ目が起こります。制御の切れ目が起こっていなければ、プログラムはステップ
11に分岐します。 |
10 |
制御の切れ目が起こった場合には、該当の制御レベル標識(L1
〜 L9)がオンにセットされます。これによってより低位の制御レベル標識もすべてオンにセットされます。プログラムによって制御フィールドの内容が保管されます。 |
11 |
合計時演算および合計時出力を行うか否かが判別されます。制御レベルを入力仕様書に指定していなければ、最初のサイクルでは合計は迂回されます。最初のサイクルの後では、合計はすべてのサイクルで処理されます。制御レベルを入力仕様書に指定した場合には、制御フィールドを含んだ最初のレコードが処理されるまで、合計は迂回されます。LR標識がオンであれば、合計は常に処理されます。 |
12 |
RPG/400言語は、制御レベル項目 (演算仕様書の 7 - 8 桁目)
で条件付けられたすべての合計演算を処理します。ENDSR
命令の演算項目2に入っているフィールド名またはリテラルの値が
*TOTCの場合には、このステップはプログラム内の戻り点になります。 |
13 |
すべての合計出力が処理されます。オーバーフロー取出し論理が指定してあり、ファイルに関連したオーバーフロー標識(OA
〜 OG、OV)がオンの場合には、オーバーフロー行が書き出されます。ファイル変換の指定がある場合には、すべての合計出力およびオーバーフロー行について行われます。ENDSR命令の演算項目2に入っているフィールド名またはリテラルの値が
*TOTLの場合には、このステップはプログラム中の戻り点になります。 |
14 |
LRがオンの場合には、プログラムはステップ 15
から続行され、そうでない場合にはプログラムはステップ 17
へ分岐します。 |
15 |
読み取った最後のレコードのデータが処理に使用できます。フィールド標識の指定があれば、すべてオンにセットされます。 |
16 |
明細演算が実行されます。ENDSR
命令の演算項目2に入っているフィールド名またはリテラルの値が
*DETCの場合には、このステップはプログラム内の戻り点になります。プログラムはステップ3へ分岐します。 |
17 |
RPG/400言語によって、ファィル仕様書(補足 E)(19〜26 桁目)にファイル名が指定されているすべての配列またはテーブルが、およびすべてのロックされたデータ域データ構造が書き出されます。また外部標識(U1
〜 U8)がリセットされます。出力配列およびテーブルは必要に応じて変換されます。 |
18 |
オープンされているファイルはすべてクローズされます。ENDSR
命令の演算項目2に入っているフィールド名またはリテラルの値が
*CANCLの場合には、プログラム内の戻り点にはステップ 18
が含まれます。またRPG/400言語は、ロックされていて(*NAMVAR DEFNステートメント)、プログラムによってアンロックされていないすべてのデータ域をアンロツクします。 |
19 |
終了 |
様々なRPGサイクルのプログラム
さて、ではここで、様々なRPGサイクルのプログラムを見ていきましょう。
前回RPGサイクルの例 BALLR1(完全なRPGサイクル)
これは、前回内容を1行づつ、見ていきましたね。サイクルの中で、I,C,O仕様書が相互に関連して、縦横無尽に制御が動き回っている姿が見えますか?
H Y/ 1
FBALLP IP E K DISK
FQPRINT O F 132 OF PRINTER
IBALLR 01
I COLOR L1
C*
C ADD 1 O1CNT 50
C*
C *INZSR BEGSR
C TIME O1TIME 60
C ENDSR
O*
OQPRINT H 101 1P
O OR OF
O 1 'H'
O 26 'NUMBER OF BALLS BALLR1'
O 43 '実行日付:'
O UDATE Y 52
O*
O H 1 1P
O OR OF
O 1 'H'
O 43 '実行時間:'
O O1TIME 52 '0 : : '
O*
O D 1 01
O 1 'D'
O COLOR 10
O*
O T 1 L1
O 1 'T'
O O1CNT JB 20 |
BALLR1の実行例
H NUMBER OF BALLS BALLR1 実行日付: 98/10/10
H 実行時間: 9:24:16
D 1緑
D 1緑
T 2
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
T 11
D 3青
D 3青
D 3青
D 3青
D 3青
T 5 |
RETRNの失敗例 BALLR2
上のソースに、一カ所だけ、訂正して、LR RETRNをつけてみました。これは、うまくいきません。I→C→Oとして、やっとレポート印刷がされるのに、最後のLRの時の、Tを出す前に、終わっているのです。つまり、I→C→[終了]となってしまっているのです。よって、最後のレコードの後の、合計が出ていませんね。サイクルの中に、出力の指定が有る場合、この様なことになります。この後に出てくる、「例外出力」のパターンと比較して下さい。
なお、*のコメントはこのように、仕様書の識別子をブランクにしても良いのです。これは、個人の好みかもしれません。
H Y/ 1
FBALLP IP E K DISK
FQPRINT O F 132 OF PRINTER
*
IBALLR 01
I COLOR L1
*
C ADD 1 O1CNT 50
*
CLR RETRN
*
C *INZSR BEGSR
C TIME O1TIME 60
C ENDSR
OQPRINT H 101 1P
O OR OF
O 1 'H'
O 26 'NUMBER OF BALLS BALLR2'
O 43 '実行日付:'
O UDATE Y 52
*
O H 1 1P
O OR OF
O 1 'H'
O 43 '実行時間:'
O O1TIME 52 '0 : : '
*
O D 1 01
O 1 'D'
O COLOR 10
*
O T 1 L1
O 1 'T'
O O1CNT JB 20 |
BALLR2の実行例:最後の合計が出ていない
H NUMBER OF BALLS BALLR2 実行日付: 98/10/10
H 実行時間: 9:24:29
D 1緑
D 1緑
T 2
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
T 11
D 3青
D 3青
D 3青
D 3青
D 3青 |
キーブレイクで改ページの例:BALLR3
今度は、キーブレイクが起きたら、合計を出して、改ページをする場合を取り上げます。改ページは、ミシン目で切り取れるため、合計単位に切り取って、配布する場合等に利用されます。いままでのプログラムとの違いは、o仕様書のHの指定です。1Pの変わりにL1が入っています。そうです、COLORが変わったら、見出し印刷をしているのです。改ページを引き起こすのは、H
101と出ていて、01へスキップする指定が有るからでしたね。
また、よく見ると、OR OFNL1と出ていますね。つまり、見出し印刷は、L1の時と、L1がオフの時にOFがオンの時、と指定しています。つまり、L1とOFが両方ONでも、2度Hの部分を実行しないようにしています。と、私も教わったのですが、確かめたことは有りません。この指定は、当然の様にされるものなので、「L1
or OFNL1」と暗記して下さい。また、この後の、レベル標識と条件標識も参考にして下さい。
H Y/ 1
FBALLP IP E K DISK
FQPRINT O F 132 OF PRINTER
IBALLR 01
I COLOR L1
C ADD 1 O1CNT 50
C*
C *INZSR BEGSR
C TIME O1TIME 60
C ENDSR
OQPRINT H 101 L1
O OR OFNL1
O 1 'H'
O 26 'NUMBER OF BALLS BALLR3'
O 43 '実行日付:'
O UDATE Y 52
O*
O H 1 L1
O OR OFNL1
O 1 'H'
O 43 '実行時間:'
O O1TIME 52 '0 : : '
O*
O D 1 01
O 1 'D'
O COLOR 10
O*
O T 1 L1
O 1 'T'
O O1CNT JB 20
|
BALLR3の実行例
H NUMBER OF BALLS BALLR3 実行日付: 98/10/10
H 実行時間: 9:24:31
D 1緑
D 1緑
T 2 |
H NUMBER OF BALLS BALLR3 実行日付: 98/10/10
H 実行時間: 9:24:31
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
T 11 |
H NUMBER OF BALLS BALLR3 実行日付: 98/10/10
H 実行時間: 9:24:31
D 3青
D 3青
D 3青
D 3青
D 3青
T 5 |
ここでは、読み込み+キーブレイクをサイクルにやらせて、印刷などの出力のタイミングを例外処理にする例です。このパターンが、実際は最も使われています。その理由は、サイクルのレベル標識(キーブレイク)は便利だけど、H,D,Tの出力のタイミングがわかりにくいからです。そこで、その出力のタイミングを、「RPGサイクルに頼らず」、サイクルから見れば、「例外的に」処理するのが、この例外出力です。
キーワードは、EXCPT(エクセプト)です。C仕様書の中で、使われています。EXCPTの後の名前が、o仕様書に有りますね。たとえば、c仕様書にEXCPT#HEDとあると、o仕様書に#HEDが有りますね。この#HEDに当たる部分を「EXCPT名」または「例外出力名」といいます。また、#...とコーディングされていますが、別に#で始まる必要は有りません。自分なりのコーディングルールをそのようにしてあるだけです。EXCPT名がきちんと1対1に定義されていないと、コンパイルでエラーになります。
さらに、RETRN命令がありますね。今度はうまくいっています。なぜでしょう。そうです。RETRNよりも、前のステップで、EXCPT#TOLの実行を完了しているからです。LRの時も、L1はオンになります。したがって、LRの時に、既に#TOLを実行して、それから。RETRNをしているので、問題がないのです。ただし、ここで、RETRNを入れる必要は得にありません。明示的に終了したいので定義したのみです。普通は、入れなくても問題有りません。
H Y/ 1
FBALLP IP E K DISK
FQPRINT O F 132 OF PRINTER
IBALLR 01
I COLOR L1
C ADD 1 O1CNT 50
C*
C OF EXCPT#HED
C EXCPT#DTL
CL1 EXCPT#TOL
CLR RETRN
C*
C *INZSR BEGSR
C TIME O1TIME 60
C EXCPT#HED
C ENDSR
OQPRINT E 101 #HED
O 1 'H'
O 26 'NUMBER OF BALLS BALLR4'
O 43 '実行日付:'
O UDATE Y 52
O*
O E 1 #HED
O 1 'H'
O 43 '実行時間:'
O O1TIME 52 '0 : : '
O*
O E 1 #DTL
O 1 'D'
O COLOR 10
O*
O E 1 #TOL
O 1 'T'
O O1CNT JB 20
|
BALLR4の実行例
H NUMBER OF BALLS BALLR4 実行日付: 98/10/10
H 実行時間: 9:24:33
D 1緑
D 1緑
T 2
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
D 2赤
T 11
D 3青
D 3青
D 3青
D 3青
D 3青
T 5 |
次回は、レベル標識と明細の条件標識に付いて、お話ししましょう。
起立、礼、着席
1998/9/27 |