画面レコードを構造体(DS)で操作する
以前、V5R4のIBMiを使っていた当時、EVAL-CORRって素敵な命令が追加された時に、ふと「画面レコードをLIKEREC」出来て、入力した値を保存だとか比較出来たら良いなぁーって思ってた。
で、V7R2にしてからRPGの解説書見ると、V6R1でもう出来る様になっているじゃないの。
RPGってさ、地味ーに進歩しているのよね。最近じゃフリーフォームのRPGを「FFのRPG」とか呼んじゃうらしく、これじゃもうゲームとしか誰もが思わなくなるんじゃないの?
画面レコードをDSで扱える前は、画面の情報を退避したり一次保存しようとすると、結構しんどかった。
- 鬼の様に変数を定義する
- 鬼の様に画面の保護フィールドを定義する
- MOVEL,MOVE,Z-ADDをフィールド単位に行う
でも、画面レコードをDSで扱えると、多くの保存領域が、欲しくてもDIMで配列数を増やす、LIKERECだから、フィールド名は元の画面フィールドのまま、転送はEVAL-CORRでめちゃ簡単。
今までは、画面でDBのレコードを呼び出して更新処理をする前に、内容変更がされてない場合は、更新したくないなんてケースは、フィールドを全部チェックしなけりゃならなかった。(※外部記述前提です。内部記述だったら一発比較でOKなんて人は知りません)
それもDS同士の比較だけで済むからすごく簡単。
簡単に出来る様になった事をあげると…
- LIKEREC等で画面レコードを選択できる(コレ事態は以前も出来たかも)
- DSだから配列にも出来る
- EXFMTでレコードの後にDS指定できる。(READ、CHAINとかと同じ感じ)
- DSだからDS同士の比較も出来る。
簡単な画面を作ってみた、入力履歴の呼出と、入力履歴の中に全く同じ内容が居たらエラーになるだけの画面。これだけだけど、項目が馬鹿みたいにある画面だと凄く有用だと思う。
最近のRPG追加機能の事、書こうと思ったけど、こっちの方が業務役立ちそうなので、これにしちゃいました。
USR400FM.DSPF
A*********************************************************************
A CHGINPDFT
A CF03(03)
A PRINT
A INDARA
A*
A R GAMEN1
A OVERLAY PROTECT
A CF09(09)
A*
A 1 10'<USR400>'
A 1 22'** 入力履歴呼出+
A **'
A COLOR(WHT)
A*
A 3 2'-------------------+
A --------------------+
A --------------------+
A -------------------'
A DSPATR(HI)
A*
A 4 2'項目1'
A GIFLD1 7Y 0B 4 12DSPATR(UL) COLOR(YLW)
A EDTCDE(4)
A*
A 6 2'項目2'
A GIFLD2 32O B 6 12DSPATR(UL) COLOR(YLW)
A*
A 8 2'項目3'
A GIFLD3 32O B 8 12DSPATR(UL) COLOR(YLW)
A*
A 9 2'-------------------+
A --------------------+
A --------------------+
A -------------------'
A DSPATR(HI)
A*
A R GAMMSG
A OVERLAY PROTECT
A GMEMSG 60O O 23 2
A COLOR(RED)
A 24 2'F3:終了F9:履歴'
USR400.RPGLE
H****************************************************************
H*-‚------------------------------*
H*-‚---<<日付・著作権 >>-----*
H*-‚------------------------------*
H DATEDIT(*YMD)
H COPYRIGHT('(C) USHIDAY - ')
H*-‚------------------------------*
H*-‚---<<コンパイル条件 >>-----*
H*-‚------------------------------*
H DFTACTGRP(*NO)
F*-š---<<ファイル定義 >>-----*
FUSR400FM CF E WORKSTN INDDS(INDICATORS)
D*-----<<画面フィールド定義>>-----*
D INDICATORS DS
D KEY@END N OVERLAY(INDICATORS:03)
D KEY@HST N OVERLAY(INDICATORS:09)
D*-š---<<変数定義 >>-----*
D*現在の画面レコード
D GCUR DS LIKEREC(GAMEN1 :*ALL)
D INZ
D*画面レコードの履歴
D GHST DS LIKEREC(GAMEN1 :*ALL)
D DIM(10)
D INZ
D*
D DUPE S N
D*
D IX S 2S 0 INZ
D*
D IX2 S 2S 0 INZ(%ELEM(GHST))
C*-‚------------------------------*
C*-‚---<<メインルーチン >>-----*
C*-‚------------------------------*
/FREE
DOW 1 = 1 ;
WRITE GAMMSG ;
EXFMT GAMEN1 GCUR ;
IF KEY@END ; //終了
LEAVE ;
ENDIF ;
IF KEY@HST ; //履歴取得
EXSR @GETHST ;
ITER ;
ENDIF ;
EXSR @CHK ; //入力チェック
IF DUPE ; //エラー
ITER ;
ENDIF ;
EXSR @SAVE ; //登録
ENDDO ;
EXSR @END ;
//入力チェック
BEGSR @CHK ;
DUPE = *OFF ;
//全く同じ内容があったらエラー
FOR IX = 1 TO %ELEM(GHST) ;
IF GCUR = GHST(IX) ;
DUPE = *ON ;
GMEMSG = '履歴'
+ %CHAR( ( %ELEM(GHST) + 1 - IX ))
+ '回前と同じ内容' ;
LEAVE ;
ENDIF ;
ENDFOR ;
ENDSR ;
//画面内容保存
BEGSR @SAVE ;
//履歴をずらす
FOR IX = 1 TO %ELEM(GHST) -1 ;
EVAL-CORR GHST(IX) = GHST(IX+1) ;
ENDFOR ;
EVAL-CORR GHST( %ELEM(GHST) ) = GCUR ;
CLEAR GCUR ;
GMEMSG = '入力内容を保存しました' ;
IX2 = %ELEM(GHST) ;
ENDSR ;
//履歴を取得
BEGSR @GETHST ;
IF IX2 <= *ZERO ;
IX2 = %ELEM(GHST) ;
ENDIF ;
EVAL-CORR GCUR = GHST( IX2 ) ;
GMEMSG = '履歴'
+ %CHAR( ( %ELEM(GHST) + 1 - IX2 ))
+ '回前の履歴' ;
IX2 -= 1 ;
ENDSR ;
//終了
BEGSR @END ;
*INLR = *ON ;
RETURN ;
ENDSR ;
/END-FREE