IBM i (旧AS400）の自己学習メモ１２　PF/LFのカラム追加に伴う再コンパイル

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

[IBM i (旧AS400）の自己学習メモ　インデックス](https://qiita.com/You_name_is_YU/items/3964849e7803c8eaf767)

# 概要

PF/LFを使ったRPGプログラミングにおいて、リリース後にテーブル定義の変更を伴う改修が必要なケースがある。
私の場合は[IBM i (旧AS400）の自己学習メモ１１　画面開発（DSPF and RPG）](https://qiita.com/You_name_is_YU/items/20958a4774939a825373)の記事の内容を進める中で、得意先マスタ（MTOKISKP）の定義で、文字列型の項目しか定義していなかったので、数値型も追加したくて、

1. カラム定義の追加
2. CHGPFコマンドですでに登録済みのデータを残した状態でテーブル定義の更新
3. LFを再コンパイル

したら、RPGプログラムも再コンパイルしないと`CPF4131`というエラーが発生してCALLできない症状が発生した。
よくよく調べてみると、どうやら`LVLCHK`なるものが影響しているということらしいので、その検証など諸々をまとめてみました。

# 初期段階のDDS（PF）

最初、以下の定義の得意先マスタを用意して、RPGプログラムを組んでいました。

```shell:MTOKISKP
 FMT A* .....A*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 
        *************** Beginning of data ***********************************************
0000.01      A* 得意先マスタ                                                           
0000.02      A*                                                                          
0001.00      A          R MTOKISKR                                                       
0001.01      A*                                                                          
0002.00      A            TOKCD          5A         COLHDG('得意先コード')             
0003.00      A            TOKNM         40O         COLHDG('得意先名')                 
0004.00      A            TOKKANA       80A         COLHDG('得意先名カナ')             
0005.00      A            TOKTEL        15A         COLHDG('電話番号')                 
        ****************** End of data **************************************************
```

# カラム定義を追加

得意先マスタに信用限度額の数値項目を１項目追加して保存します。

```shell:MTOKISKP
 FMT A* .....A*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
        *************** Beginning of data **********************************************
0000.01      A* 得意先マスタ                                                          
0000.02      A*                                                                         
0001.00      A          R MTOKISKR                                                      
0001.01      A*                                                                         
0002.00      A            TOKCD          5A         COLHDG('得意先コード')            
0003.00      A            TOKNM         40O         COLHDG('得意先名')                
0004.00      A            TOKKANA       80A         COLHDG('得意先名カナ')            
0005.00      A            TOKTEL        15A         COLHDG('電話番号')                
0006.00      A            TOKRMT         9P 0       COLHDG('信用限度額')              
        ****************** End of data *************************************************
```

このあと、OPTに`14`を指定して再コンパイルする際、`Delete existing object`に`Y`を指定しなければならず、すでに登録済みのデータが消えてしまうので、データを消さずにテーブル定義の変更を行うため、以下のCHGPFコマンドを実行しました。

```shell
chgpf file(yamaguchi1/mtokiskp) srcfile(yamaguchi1/qddssrc)  
```

`MTOKISKL00`という論理ファイルも１つあったので、論理ファイルは再コンパイルしました。
（物理的なデータを保持しているわけではないので、再作成のつもりで再コンパイルしました。）

# 定義追加後にRPGプログラムを実行するとCPF4131エラー

テーブル定義の修正後、RPGプログラムを実行すると以下のエラーが発生しました。

```shell
Error message CPF4131 appeared during OPEN for file MTOKISKL00 (C S D F). 
```

詳細なメッセージの内容は

```shell
                        Additional Message Information                       
                                                                             
Message ID . . . . . . :   RNQ1216       Severity . . . . . . . :   99       
Message type . . . . . :   Inquiry                                           
Date sent  . . . . . . :   20-04-26      Time sent  . . . . . . :   08:33:14 
                                                                             
Message . . . . :   Error message CPF4131 appeared during OPEN for file      
  MTOKISKL00 (C S D F).                                                      
Cause . . . . . :   RPG procedure RPG01 in program YAMAGUCHI1/RPG01 received 
  the message CPF4131 while performing an implicit OPEN operation on file    
  MTOKISKL00. The actual file is MTOKISKL00.                                 
Recovery  . . . :   Check the job log for a complete description of message  
  CPF4131, and contact the person responsible for program maintenance. If the
  file has a device type of SPECIAL, there may be no message in the job log. 
Possible choices for replying to message . . . . . . . . . . . . . . . :     
  D -- Obtain RPG formatted printout of system storage.                      
  S -- Obtain printout of system storage.                                    
  F -- Obtain full formatted printout of system storage.      
  C -- Cancel.               
```

# 解消方法

まず、PF/LFのコンパイルをする際、OPTに`14`を指定して、F4キーを押下してプロンプトを表示し、Record format level check の設定を`*NO`にしてコンパイルを行う。

```shell
                         Create Physical File (CRTPF)        
                                                             
Type choices, press Enter.                                   
                                                             
Coded character set ID . . . . . CCSID          *JOB         
Allow update operation . . . . . ALWUPD         *YES         
Allow delete operation . . . . . ALWDLT         *YES         
Record format level check  . . . LVLCHK         *NO          
Node group . . . . . . . . . . . NODGRP         *NONE        
  Library  . . . . . . . . . . .                             
Partitioning Key . . . . . . . . PTNKEY                      
                          + for more values                  
Authority  . . . . . . . . . . . AUT            *LIBCRTAUT   
```

こうすると、RPGプログラムを実行してもエラーが発生せずに正常に利用できる。

# LVLCHK=*NO の問題点

今回試しにおこなったカラム追加は、ファイル定義の一番最後に、信用限度額の項目を追加した場合でうまくいきました。
では、どこか途中にカラム定義を追加した場合はどうなるのでしょうか？

試しに郵便番号のカラムを途中に追加してみました。

```shell:MTOKISKP
 FMT A* .....A*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
        *************** Beginning of data **********************************************
0000.01      A* 得意先マスタ                                                          
0000.02      A*                                                                         
0001.00      A          R MTOKISKR                                                      
0001.01      A*                                                                         
0002.00      A            TOKCD          5A         COLHDG('得意先コード')            
0003.00      A            TOKNM         40O         COLHDG('得意先名')                
0004.00      A            TOKKANA       80A         COLHDG('得意先名カナ')            
0004.01      A            TOKPOST        8A         COLHDG('郵便番号')                
0005.00      A            TOKTEL        15A         COLHDG('電話番号')                
0006.00      A            TOKRMT         9P 0       COLHDG('信用限度額')              
        ****************** End of data *************************************************
```

この状態で、CHGPFを実行してテーブル定義を反映させても、RPGプログラムを再コンパイルすることなく、正常に実行することができました。

ただ、エラーがなく実行できたものの問題が発生しました。
それは、サンプルで開発していたRPGプログラムの得意先情報を参照する機能において、電話番号の表示が８バイト右にずれてしまい、下5桁の電話番号が画面上から欠落してしまったのです。

```shell:Before
   電話番号・・・・・・ 03-1111-1111     
```

```shell:After                                    
   電話番号・・・・・・         03-1111                                                                                                   
```

カラムの追加を項目の途中に行うと、その定義のサイズだけ勝手にずれてしまうので、LVLCHKを*NOにすればいいというものではなさそうです。

該当のテーブルを参照しているRPGプログラムなどを全部再コンパイルしなければいけないのは面倒なのですが、チェックをしないと、それはそれで、上記のような思いもしないバグを発生させてしまうので悩ましいものです。

せめて対象のPFやLFを参照しているRPGプログラムなどを、一覧で取得したりできる機能があればいいんですが。。
そんな機能があるなら誰か教えてください。。。