0
2

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 3 years have passed since last update.

IBM i (旧AS400)の自己学習メモ RPG Ⅳプログラミング編02 コンパイル時配列(CTDATAを使う)

Last updated at Posted at 2020-05-04

自己学習メモインデックス

IBM i (旧AS400)の自己学習メモ インデックス

概要

RPG Ⅳプログラミングでコンパイル時配列を使って得意先マスタメンテナンス画面のモード切替(登録,更新,削除)を切り替えるような作りにしたかったのですが、なかなかうまく機能しなかったので、その内容をまとめてみました。
ここでも基本はフリーフォーマットではなく定位置記入方式でRPGプログラミングをしていきます。

参考にした情報

以下のサイトにあるような、DIMキーワードとCTDATAキーワードを使った、コンパイル時配列の初期以下を行います。
https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rzasd/ctrule.htm

      DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords++++++++++++++++++++
      DARC              S              3A   DIM(12) PERRCD(5) CTDATA
**CTDATA ARC
48K16343J64044HComments can be placed here
12648A47349K346Comments can be placed here
50B125         Comments can be placed here

試行錯誤した内容

上記サンプルコードは、インターネットでAS400 RPG CTDATA コンパイル時配列などのキーワードで検索すると、似たようなコードが出てきます。
そこで、ちょうど今得意先マスタメンテナンス画面の実装を進めており、マスタメンテナンスによくあるような登録,更新,削除のモードを切り替えて、そのモードの文字列を画面上に表示するために、登録,更新,削除の文字列をコンパイル時配列に格納しようと思い、以下のようにコーディングしました。

 FMT *   *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 
        *************** Beginning of data ******************************************
0001.00  * コンパイル時配列用の変数定義                                           
0002.00 D @@MODES         S              6    DIM(3)  CTDATA PERRCD(1)              
0003.00  * コンパイル時配列の値を表示                                             
0003.02 C     @@MODES(1)    DSPLY                                                   
0006.00  * RPGの終了                                                              
0007.00 C                   EVAL      *INLR = *ON                                   
0008.00  * コンパイル時配列の初期値設定                                           
0009.00 **CTDATA @@MODES                                                            
0010.00 登録                                                                      
0011.00 更新                                                                      
0012.00 削除                                                                      
        ****************** End of data *********************************************

すると、SEUでEnter押下時にハイライト表示されている部分でForm-Type entry for main procedure not valid or out of sequence.と怒られてしまいました。

スクリーンショット 2020-05-04 10.10.03.png

確かにサンプルコードとよく比較してみると、D仕様書のDキーワードの部分とCTDATAの2個目のTの部分が一致するように記述されているので、この状態ではいけないのはわかります。
だからといって、こんな風に行番号の部分を侵食してサンプルコードのような書き方をするとUser exit program processing error. と怒られます。

スクリーンショット 2020-05-04 10.13.51.png

いったいどうやって行番号の部分を侵食してサンプルコードのようなことができるのか。。。
参考にしたサイトにも

  • 配列ソース・レコードについては、次の規則があります。
    • 各レコードの最初の配列項目は、1 桁目から始めなければなりません。
    • すべての要素は同じ長さで、中間にスペースを入れずに各要素が続いていな ければなりません。
    • レコード全体に項目を埋め込む必要はありません。 そうでない場合には、項 目の後にブランクまたは注記を含めることができます (図 1 を参照)。
    • 定義仕様書に指定された配列の要素の数が指定された項目の数より大きい場合 には、残りの要素には指定されたデータ・タイプのデフォルトの値によって埋め込みが 行われます。

という記載があります。ここでの1桁目からというのが、行番号のエリアにはみ出てコーディングしなければいけないということなんだろうと思ったのですが、ここでパニックになりました。

試行錯誤するうちに、SEUの画面下部にある各ファンクションキーに目を向けました。
F11キー:Toggleが怪しいかなと思ったのですが、SEUの画面がちょっと右にずれるだけで、期待した結果にならず、、、
F24でMore Keysを見ていると、F20=Rightというのが出てきました。
F20キーを押下すると、SEUの画面にさらなる余白部分が登場しました!

スクリーンショット 2020-05-04 10.17.56.png

今までD仕様書やC仕様書のDCがSEUの1桁目だったのに対し、F20キーを押下した後はさらに左側にスペースができて、ちゃんと1桁目っぽい領域が登場しました。

なるほど。SEUは各仕様書を記載しやすいようにわざと1桁目が仕様書を表すキーワードを指定するポジションとしていて、必要に応じて位置をずらせるようにしているんですね。

様々なサイトでコードのサンプルを載せてくれている人たちにとっては、これって知ってて当たり前の内容なんでしょうか?
私みたいに、これが出来ずに数時間も悩み続けてしまう素人もいるってことと、他にも同じように悩んでいる人がいたら、これを参考にしてもらえればと思ってQiita記事にまとめてみました。

# 最終的に解決したコード

まず、SEUを起動してF20キーを押下しておくこと。
※DとかCのキーワードより左側に位置するように** CDATA @@MODESなどを定義するためには、F20キーを押下する必要がある。
そのうえで、以下のRPGをコーディング。

 FMT *  ..... *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 
        *************** Beginning of data ***********************************************
0001.00       * コンパイル時配列用の変数定義                                           
0002.00      D @@MODES         S              6    DIM(3)  CTDATA PERRCD(1)              
0002.01       * インデックス変数                                                       
0002.02      D i               S              1P 0 INZ(1)                                
0003.00       * コンパイル時配列の値を表示                                             
0003.01      C                   FOR       i = 1 to 3 by 1                               
0003.02      C     @@MODES(i)    DSPLY                                                   
0003.03      C                   ENDFOR                                                  
0006.00       * RPGの終了                                                              
0007.00      C                   EVAL      *INLR = *ON                                   
0008.00       * コンパイル時配列の初期値設定                                           
0010.00 ** CTDATA @@MODES                                                                
0011.00 登録                                                                           
0012.00 更新                                                                           
0013.00 削除                                                                           
        ****************** End of data **************************************************

実行すると以下のように処理モードの文字列が画面上に出力されます。

DSPLY  登録 
DSPLY  更新 
DSPLY  削除 
  • 6
    • 配列1要素あたりのサイズ
    • AとかPとか指定していないが、指定しなくてもいいみたい。
  • DIM(3)
    • 配列の要素数が3となる配列を定義する。
  • CTDATA
    • コンパイル時にデータをロードして初期化されることを表す。
  • PERRCD(1)
    • レコードあたりの要素数を表す。
    • ここでは1を指定しているので3つの要素の1次元配列という意味合いで理解。
    • 2以上を指定すると、DIMが行で、PERRCDが列となるようなテーブルのような配列となる。
0001.00       * コンパイル時配列用の変数定義                                           
0002.00      D @@MODES         S              6    DIM(3)  CTDATA PERRCD(1)  
  • ** CTDATA @@MODES
    • コンパイル時に配列のデータを初期化することを表すキーワード
    • @@MODESの配列を初期化することを表す。
  • 登録,更新,削除
    • 特にシングルクォートやダブルクォートで囲む必要はなく、初期化用のデータを列挙する。
0008.00       * コンパイル時配列の初期値設定                                           
0010.00 ** CTDATA @@MODES                                                                
0011.00 登録                                                                           
0012.00 更新                                                                           
0013.00 削除    
0
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?