0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ILE RPGAdvent Calendar 2015

Day 3

RPGで動的配列

Last updated at Posted at 2015-12-02

先日の投稿「画面レコードを構造体で操作する」で5250画面に入力履歴の機能を付けました。10履歴固定で行ったので、今回は動的配列を使って可変でやった場合のサンプルです。
動的記憶域を使う場合は、RPGの命令とBIFを使うか、APIを使うパターンがあります。
今回は命令とBIFを使ったパターンで、前者はデフォルトヒープが使用され、活動化グループに依存します。後者は、ユーザー自身が任意でヒープを作るパターンで、初期サイズや拡張サイズなどをコントロールする事が出来ます。
静的配列と動的配列の2つのプログラムをDSPPGMで確認すると静的記憶域のサイズが若干小さくなってます。
●静的配列
2015-12-02_154805.png

●動的配列
2015-12-02_154905.png

USR400A.rpgle
     H****************************************************************
     H*-‚------------------------------*
     H*-‚---<<日付・著作権    >>-----*
     H*-‚------------------------------*
     H DATEDIT(*YMD)
     H COPYRIGHT('(C) CHUBU SYSTEM CO,.LTD 1996 - ')
     H*-‚------------------------------*
     H*-‚---<<コンパイル条件  >>-----*
     H*-‚------------------------------*
     H DFTACTGRP(*NO) ACTGRP(*NEW)
     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(8192)
     D                                     BASED(GHST@)
     D*
     D DUPE            S               N
     D*
     D IX              S              4S 0 INZ
     D HSTNOW          S              4S 0 INZ
     D*
     D NOW             S              4S 0 INZ
     D ARYMAX          S              4S 0 INZ
     D EXTEND          C                   10
     D SIZE            S              9B 0 INZ
     C*-‚------------------------------*
     C*-‚---<<メインルーチン  >>-----*
     C*-‚------------------------------*
      /FREE
           //画面履歴の配列を記憶域に割り振る
           ARYMAX += EXTEND  ;
           SIZE   = %SIZE(GHST) * ARYMAX ;
           GHST@  = %ALLOC(SIZE) ;
           FOR  IX = 1 TO ARYMAX         ;
               CLEAR GHST(IX) ;
           ENDFOR           ;

           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 NOW         ;
                IF GCUR = GHST(IX)   ;
                    DUPE = *ON    ;
                    GMEMSG = '履歴'
                           + %CHAR( NOW -IX + 1  )
                           + '回前と同じ内容' ;
                    LEAVE   ;
                ENDIF            ;
              ENDFOR           ;
           ENDSR            ;

           //画面内容保存
           BEGSR  @SAVE     ;
              NOW  += 1     ;
             //配列を拡張
              IF NOW > ARYMAX ;
                  ARYMAX += EXTEND  ;
                  SIZE = %SIZE(GHST) * ARYMAX ;
                  GHST@  = %REALLOC(GHST@ : SIZE)  ;
                  //要素を初期化
                  FOR  IX = NOW TO ARYMAX         ;
                      CLEAR GHST(IX) ;
                  ENDFOR           ;
              ENDIF ;
              EVAL-CORR GHST( NOW ) = GCUR  ;
              CLEAR GCUR ;
              GMEMSG = '入力内容を保存しました' ;
              HSTNOW = *ZERO ;
           ENDSR            ;

           //履歴を取得
           BEGSR  @GETHST   ;
              HSTNOW += 1 ;
              IF HSTNOW > NOW ;
                 HSTNOW = 1 ;
              ENDIF     ;
              EVAL-CORR GCUR = GHST( NOW - HSTNOW + 1 )  ;
              GMEMSG = '履歴'
                         + %CHAR( HSTNOW )
                         + '回前の履歴' ;
           ENDSR            ;

           //終了
           BEGSR  @END      ;

             //配列の記憶域解放
             DEALLOC  GHST@ ;

             *INLR = *ON    ;
              RETURN        ;
           ENDSR            ;

      /END-FREE 

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?