フリー・フォーマット RPG で対話型アプリケーション (顧客名による顧客情報の検索)

メインメニューから F7 キーを押したことで呼び出される処理は、顧客データを 顧客名(アルファベット)をキーにして検索する処理です。

画面イメージはこちらにあります。


画面の定義

画面ファイルの定義です。

     A*****************************************************************
     A* ファイル名: SNAMMENU                                         *
     A* 関連プログラム: SCHNAM                                      *
     A* 関連ファイル: CUSMSTL3 (論理ファイル)                       *
     A* 説明: これは表示ファイルSNAMMENU です。7 つの             *
     A*       レコード様式があります                                 *
     A*****************************************************************
     A                                      REF(CUSMSTL3)
     A                                      CHGINPDFT(CS)
     A                                      PRINT(QSYSPRT)
     A                                      INDARA
     A                                      CA03(03 'END OF JOB')
     A          R HEAD
     A                                      OVERLAY
     A                                  2  4TIME
     A                                      DSPATR(HI)
     A                                  2 25'CUSTOMER SEARCH & INQUIRY BY NAME'
     A                                      DSPATR(HI UL)
     A                                  2 70DATE
     A                                      EDTCDE(Y)
     A                                      DSPATR(HI)
     A          R FOOT1
     A                                 23  6'ENTER - Continue'
     A                                      DSPATR(HI)
     A                                 23 29'F3 - End Job'
     A                                      DSPATR(HI)
     A          R FOOT2
     A                                 23  6'ENTER - Continue'
     A                                      DSPATR(HI)
     A                                 23 29'F3 - End Job'
     A                                      DSPATR(HI)
     A                                 23 47'F4 - Restart Name'
     A                                      DSPATR(HI)
     A          R PROMPT
     A                                      OVERLAY
     A                                  5  4'Enter Search Name'
     A                                      DSPATR(HI)
     A            SRCNAM    R        I  5 23REFFLD(NAME CUSMSTL3)
     A                                      DSPATR(CS)
     A          R SUBFILE                   SFL
     A                                      CHANGE(99 'FIELD CHANGED')
     A            SEL            1A  B  9  8DSPATR(CS)
     A                                      VALUES(' ' 'X')
     A            ZIP       R        O  9 54
     A            CUST      R        O  9 43
     A            NAME      R        O  9 17
     A          R SUBCTL                    SFLCTL(SUBFILE)
     A                                      SFLSIZ(0013)
     A                                      SFLPAG(0013)
     A  55                                  SFLCLR
     A N55                                  SFLDSPCTL
     A N55                                  SFLDSP
     A                                      ROLLUP(95 'ROLL UP')
     A                                      OVERLAY
     A                                      CF04(04 'RESTART SEARCH NAME')
     A                                  5  4'Search Name'
     A            SRCNAM    R        O  5 17REFFLD(NAME CUSMSTL3)
     A                                      DSPATR(HI)
     A                                  7  6'Select'
     A                                      DSPATR(HI)
     A                                  8  6' "X" Customer Name '
     A                                       DSPATR(HI)
     A                                       DSPATR(UL)
     A                                  8 42' Number Zip Code '
     A                                       DSPATR(HI)
     A                                       DSPATR(UL)
     A          R CUSDSP
     A                                       OVERLAY
     A                                  6 25'Customer'
     A            CUST           5S 0O  6 35DSPATR(HI)
     A                                  8 25'Name'
     A            NAME          20A  O  8 35DSPATR(HI)
     A                                 10 25'Address'
     A            ADDR1         20A  O 10 35DSPATR(HI)
     A            ADDR2         20A  O 11 35DSPATR(HI)
     A                                 13 25'City'
     A            CITY          20A  O 13 35DSPATR(HI)
     A                                 15 25'State'
     A            STATE          2A  O 15 35DSPATR(HI)
     A                                 15 41'Zip Code'
     A            ZIP            5S 0O 15 50DSPATR(HI)
     A                                 17 25'A/R Balance'
     A            ARBAL         10Y 2O 17 42DSPATR(HI)
     A                                      EDTCDE(J)

ビュー

得意先マスターに顧客名をキーにしたビューを定義します。

     A*****************************************************************
     A* ファイル名: CUSMSTL3                                          *
     A* 関連プログラム: SCHNAM                                        *
     A* 関連ファイル: CUSTOMER (物理ファイル)                         *
     A* 説明: これは論理ファイルCUSMSTL3 です。これには               *
     A*       1 つのレコード様式CUSTOMER があります。                 *
     A*       これは得意先マスター・ファイル(CUSTOMER) の             *
     A*       得意先名(NAME) による論理ビューです。                   *
     A*****************************************************************
     A          R CUSTOMER                  PFILE(CUSTOMER)
     A          K NAME

プログラム

こちらのプログラムに関しては、もともと得意先名がユニークであることが前提となっており、そのため顧客名順の論理ファイルを顧客名(の先頭から一部)をキーにしてアクセスするようになっています。

じつは今回生成したデータでは、得意先名には重複があり、名前と顧客番号をあわせてユニークになっています。
以下のプログラムでは、サブファイルのリストから明細を表示させる際に得意先名をキーにしてデータを持ってきているので、指定したデータがたまたまリストで同一得意先名の一番上だったりした場合以外には、一致したデータが表示されなくなってしまいます。
そこで、今回は顧客番号をキーにしたビュー/論理ファイルである CUSMSTL1 を、詳細データをアクセスするためのビューとして使用するように変更しました。

      //****************************************************************
      // プログラム名: SCHNAM                                          *
      // 関連ファイル: CUSMSTL3 (論理ファイル)                         *
      //             : CUSMSTL1 (論理ファイル)                         *
      //               NAMMENU (WORKSTN ファイル)                      *
      // 説明: このプログラムは、WORKSTN サブファイル処理を            *
      //       使用した得意先マスター検索プログラムです。              *
      //       このプログラムは、得意先名でユーザーに                  *
      //       プロンプトを出し、setll 命令でのcusmstl3 の             *
      //       位置付けにそれを使用します。さらにサブファイル          *
      //       を使ってレコードを表示します。                          *
      //       他のページを充填するために、ロールアップ・              *
      //       キーを押します。得意先詳細を表示するには、「X」         *
      //       をその得意先のところに入れ、Enter を押します。          *
      //       プログラムを終了するためにPF3 を押します。              *
      //****************************************************************

     Fcusmstl3  if   e           K DISK
     Fsnammenu  cf   e             workstn sfile(subfile:recnum)
     F                                     indds(indicators)
     Fcusmstl1  if   e           k disk

      // プロトタイプ定義:
     D ProcessSubfile  PR
     D DisplayDetail   PR
     D ClearSubfile    PR
     D FillSubfile     PR

      // フィールド定義:
     D recnum          s              5p 0
     D indicators      ds
     D exitKey                         n   overlay(indicators:3)
     D restartKey                      n   overlay(indicators:4)
     D sflClear                        n   overlay(indicators:55)
     D rollupKey                       n   overlay(indicators:95)

      //******************************************************************
      // メインライン                                                    *
      //******************************************************************
      /free

       write foot1;
       write head;
       exfmt prompt;

       // 終了キーが押されるまでループする
       dow not exitKey;

          setll (srcnam) customer;
          ProcessSubfile();
          DisplayDetail();

          // 終了キーがサブファイル表示で押された場合は、ループを出る
          if exitKey;
             leave;
          endif;

          // 再始動キーがサブファイル表示で押された場合は、ループを繰り返す
          if restartKey;
             iter;
          endif;

          write foot1;
          write head;
          exfmt prompt;

       enddo;

       *inlr = *on;

      /end-free

       //*****************************************************************
       // プロシージャ- ProcessSubfile                                   *
       // 目的- サブファイルを処理し、表示する                           *
       //*****************************************************************
     P ProcessSubfile  B
     D ProcessSubfile  Pi
      /free

          // ロールアップ・キーが押されるまでループする
          dou not rollupKey;

             // サブファイルに追加する情報は他にあるか?
             if not %eof(cusmstl3);
                // サブファイルを消去し、得意先データで充填する
                ClearSubfile();
                FillSubfile();
             endif;

             // サブファイルを書き出し、応答を待つ
             write foot2;
             exfmt subctl;

          enddo;

      /end-free
     P ProcessSubfile  E

       //******************************************************************
       // プロシージャ- FillSubfile                                       *
       // 目的- サブファイルを充填する                                    *
       //******************************************************************
     P FillSubfile     B
     D FillSubfile     Pi
      /free

          // 指定した郵便番号で得意先レコード全体をループする
          recnum = 0;

          dou %eof(snammenu);

             // 指定した郵便番号で次のレコードを読み取る
             read customer;

             if %eof(cusmstl3);
                // レコードがなくなったら、以下を行う
                return;
             endif;

             // このレコードの情報をサブファイルに追加する
             recnum = recnum + 1;
             sel = *blank;
             write subfile;

          enddo;

      /end-free
     P FillSubfile     E

       //****************************************************************
       // プロシージャ- ClearSubfile                                    *
       // 目的- サブファイル・レコードの消去                            *
       //****************************************************************
     P ClearSubfile    B
     D ClearSubfile    Pi
      /free

          sflClear = *on;
          write subctl;
          sflClear = *off;

      /end-free
     P ClearSubfile    E

       //*****************************************************************
       // プロシージャ- DisplayDetail                                    *
       // 目的- 指定した得意先レコードの表示                             *
       //*****************************************************************
     P DisplayDetail   B
     D DisplayDetail   Pi
      /free

          // サブファイルの変更されたレコード全体をループする
          readc subfile;

          dow not %eof(snammenu);
             // 要求した得意先レコードの表示を再始動する
             restartKey = *on;
             // 得意先レコードを検索し、表示する
             // (今回生成したデータ用にキーを変更しています) 
             chain (cust) CMLREC1 ;
             exfmt cusdsp;

             // 終了キーが押される場合は、ループを終了する
            if exitKey;
               leave;
            endif;

            readc subfile;

          enddo;

      /end-free
     P DisplayDetail   E

内容は「フリー・フォーマット RPG で対話型アプリケーション (Zip コードによる顧客情報の検索)」とあまり変わりません。今までの解説とあわせて、見てみてください。

まず最初にフッター、ヘッダーを画面に書き、プロンプト画面で入力を待ち、入力を受け取ります。
(exfmt 命令は、入力用の画面を表示し、Enter キーを押されて返ってきた結果を受け取る、という複合的な処理をこなします)

       write foot1;
       write head;
       exfmt prompt;

exfmt 命令の結果、exitKey が押されていればそこで終了(doW ループには入らない)ですし、そうでなく空欄か何らかの文字が入力されていた場合(されているとすれば srcnam というフィールドに入っています)は、その値を元に customer テーブルにカーソルをセットします。空欄だった場合は、一番下の値にセットされます。

       dow not exitKey;

          setll (srcnam) customer;

customer テーブルにカーソルがセットされた状態を引き継いで ProcessSubfile 処理と DisplayDetail 処理が行われます。

          ProcessSubfile();
          DisplayDetail();

ProcessSubfile 処理の中を見てみましょう。

まず最初は DoU (Do Untill) なので無条件に Do ループの中は実行されます。

     P ProcessSubfile  B
     D ProcessSubfile  Pi
      /free

          dou not rollupKey;

顧客名順のビューが最後のレコードに突き当たっていないのであれば、
「サブファイル」という画面ファイルの中の RDB のテーブルのように扱えるデータバッファをいったんクリアしてから、
その中に顧客名順ビュー経由のデータを蓄積します。

             if not %eof(cusmstl3);
                ClearSubfile();
                FillSubfile();
             endif;

ClearSubfile 処理は、サブファイルをクリアする、という意味のビットを立てて画面ファイルに伝えてやることで行われます。

          sflClear = *on;
          write subctl;
          sflClear = *off;

FillSubfile 処理は、顧客名順ビューの最終レコードまで読んで「サブファイル」にそれを書き込みます。

          recnum = 0;

          dou %eof(snammenu);

             read customer;

             if %eof(cusmstl3);
                return;
             endif;

             recnum = recnum + 1;
             sel = *blank;
             write subfile;

          enddo;

ProcessSubfile 処理の中で、フッターを画面に出力し、サブファイルを表示させ、入力を待ちます。

             // サブファイルを書き出し、応答を待つ
             write foot2;
             exfmt subctl;

          enddo;

サブファイルで表示されるデータの左側に、そこに "X" を入力すると詳細画面が表示されるようになっている入力フィールドがあります。

続く DisplayDetail 処理では、その入力フィールドに入力があるかどうかをスキャンして(readc 命令のお仕事です)、それがあれば明細画面を exfmt cusdsp 命令で出しますし、すぐ前の ProcessSubfile 処理で F3 キーが押されていればそれを受け取ってこのループを出ます(exitKey は誰もオフにしていないので、オンのままです。なので次のループもその条件を受け取って終了します)し、何も入力がなければそのままこの処理を出ます。

     P DisplayDetail   B
     D DisplayDetail   Pi
      /free

          readc subfile;

          dow not %eof(snammenu);
             restartKey = *on;
             chain (cust) CMLREC1 ;
             exfmt cusdsp;

            if exitKey;
               leave;
            endif;

            readc subfile;

          enddo;

DisplayDetail 処理を終わって exitKey がオンのままであれば、メイン・ロジックの doW ループも終了します。
(leave 命令であたまの dow に行き、そこで dow not exitKey なのでループ終了、となりますね)

          if exitKey;
             leave;
          endif;

右下に "F4 - Restart Name" とありますが、

↑の画面で F4 キーを押すと再度検索のし直しが行われます。
iter 命令というのは、後続処理を飛ばしてループの最初に戻る、という命令ですので、また処理のし直しになるというわけですね。

          if restartKey;
             iter;
          endif;

          write foot1;
          write head;
          exfmt prompt;

       enddo;

最後のフッター、ヘッダー、入力画面の表示/入力の受け取りについてはいいですね。
一番最初にあった処理と同じです。Do While ループの場合、よくある書き方です。

[Top Pageに戻る]

Ads by TOK2