Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@ushiday

RPGで動的配列

先日の投稿「画面レコードを構造体で操作する」で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 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?