[解説10]
この10という数字は、1ページ当たりのレコード数(行数)のことです。プログラム内で一個所に定義して、以降はこの#PAGSZを参照してあれば、修正も楽です。(ここに定義したのは、これだけの目的です。)

[解説20]
後で、説明しますが、1ページサブファイルにロードして、表示して、ロールアップが押されたら、その続きを、ロードしなくてはなりません。つまり、何行までレコードを書き出しているかを、どこかに取っておく必要があります。このW1RN01が、その保管専用フィールドです。

 [解説30]
ロールアップが押されると、ここに戻ります。(GOTOが嫌いな方はこのロジックで、ご自分で構造化して下さい。ここでは、ソースの理解だけにして下さい。)ここで、続きのレコードをサブファイルに「書き足す」のです。そして、もちろん、次に表示するのは、その「書き足した」ページを表示してあげねばなりません。でないと、いくらロールアップを押して、プログラム内部で、レコードを1ページ1ページ作成しても、オペレータの目には、相変わらず最初のページだけとなってしまいます。

 [解説35]
もし、\INZに処理が戻ると、サブファイルは空になります。(SFLCLR + SETLLがありますよね。わざと分かりやすいようにソースにのせてあります。)つまり、最初からやり直しとなります。だから、\INZに飛ぶのは、表示開始位置の変更や、再表示(F5)のときだけです。

 [解説40]
読み込んでいるファイルが、EOFでなければ、ロールアップを許可しています。逆に、EOFになると、\INZに戻らない限り、この部分はスキップされ、READCの処理に進みます。ここで、いちいちEOFを判定しなくても、ファイルカーソルは既にEOFなので、本来、レコードをREADしても、(SETLLしてないので)読み込むレコード数は変わらないはずです。あくまで、説明上明示的にコードしました。

 ※但し、頻繁にレコードが追加されるファイルだと困るかもしれません。つまり、一度、EOFになると、画面に表示されたレコードの後のレコードは表示されません。(説明上、そういうロジックにしてあるから)。これは、あくまでオペレータに如何にEOF後のレコードを分からせるかという問題です。画面上、いったんEOFになると右下に「終わり」(SFLEOF(*MORE)の機能)が出ているのに、さらにレコードを表示するのは混乱を招くかもしれません。ここからは、このソースに入れてありません。つまり、いったんEOF後に新レコードを発見した場合の特別処理をいれるか、SEUのB(BOTTOM)の機能(最終レコードを一気に見せる)をいれるか、いろいろ方法はあるのですが、サブファイルのプログラムのロジックを理解する目的から外れると思うので、この件は皆さん自身で考えて下さい。

 [解説50]
W1CNTはレコードを何件書き出したかのカウンターの役目です。このカウンターが#PAGSZ(=10)と同じになるまで、サブファイルレコードを書き出します。

 [解説55]
先ほど出てきた、EOFのフラグの待避フィールドです。

 [解説60]
サブファイルのレコードのRRNは、サブファイルがクリアされたら、0にリセットします。このほかに、W1RN01も「必ず」リセットします。このW1RN01は、サブファイルのレコードの現在の件数を保持します。つまり、サブファイルのレコードのRRNの開始番号を制御しています。

[解説70]
ここからが、パターン2の心臓部分です。このパターン2はよく、「自動拡張」などといわれます。DSPFのDDSを見ると分かりますが、SFLPAGとSFLSIZは一致していません。もし、同じだと、「自動拡張」はできずWRITE SFL01でSFLPAG=SFLSIZの件数を超えた時点で、エラーになります。

 [解説80]
サブファイルのレコードセットの手順は、

  1. 前回の最後のRRN(W1RN01)を、RRN01にセット。(もし最初のレコードならRRN01は0、1ページ10行で、2ページ目の処理の開始時点ならば、RRN01は10になるわけです。(+1してからWRITEしています)
  2. このRRN01をカウントしながら、10件書き出します。この10件かいなかを判定するのは、W1CNTの内容です。( 1   DO  10でも可能ですが、もしREADの後で、条件を満たさないレコードをスキップする処理をいれてしまうと、 1    DO  10 ではうまく動きません。)
  3. サブファイル書き出しのとき、最初に表示すべきページの制御を@TOSFLでしています。
  4. ファイルがEOFか、10件書き出したら、ループから抜けます。

これだけです。

[解説90]
ここで、次回のサブファイルセットに備えて、最後のRRN01を、W1RN01に待避します。
ところで、何で、RRN01を別のW1RN01にわざわざ取っておくか分かりますか。これは、ロールアップを押されて次に@BDSFLに来る前に、「READC」の処理をするからです。READCやCHAINで、RRN01の内容は書き換わってしまうのです。

[解説100]
この部分は、しなくても、サブファイルは正常に表示されます。ここでは標識63つまりSFLEND(*MORE)を処理しようとしているだけです。この「続く..」や「終わり」という文字を右下に出す部分のチェックです。パターン1はこんなことしてなかったですよね。あれはEOFになるまで全件処理するので必要ないのです。ではパターン2ではどうなるのでしょうか。
つまり、もしレコードが10件で、DOループも10件だと、(1ページの行数と読み込むレコード数が偶然同じ場合など)、EOFにならないまま、ループを抜けてしまうのです。「続く..」とでて、オペレータに期待させて、いざロールアップをおすと、同じページがでて、急に「終わり」になってしまうのです。それで、一件先読みをして、EOFなら、「終わり」にして、EOFでなければ、先読みをした分、一件前に戻るのです。

[解説110]
件数の判定用にカウントしています。

 [解説120]
もし、書き出しの最初の一件目ならば、H1SRCD(SFLRCDNBR)にRRN01をセットします。これで、この次に表示するのは、このレコード(つまり、新しいページの先頭行)を含むページとなります。

 このあとは、パターン1と同じです。

SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送