RPG

531. %LOOKUP のバグ(?)と対策方法

ILE-RPG フリー・フォーマットで
%LOOKUPは使い慣れると大変便利な
組込み関数である。
_

 N = %LOOKUP(RECORD: RECR);

のようにしてレコード名 : RECORDを
レコード名の配列 : RECRをLOOKUPして
見つかれば N に見つかった指標の値が
入る。
見つからなければ N = 0 となる。
これは固定記述の以下の演算と同じである。

            Z-ADD1       N
 RECORD     LOOKUP RECR(N)           50

のようにいつも記述してきたはずである。
ところで

            Z-ADD1      N

として開始の指標をセットしたきたのだが

N = %LOOKUP(RECORD: RECR);

では開始の指標の位置は指定していない。
省略値は 1 のはずであるが
いろいろな場面で試したところ
配列 RECRに要素 RECORDが登録されているのに
%LOOKUPで見つからなくて N = 0 が戻ってしまう場合が
発生された。
_

これを防ぐには

N = %LOOKUP(RECORD: RECR: 1);

として検索開発位置を明示的に 1 をセットしておけば
このようなバグは発生しない。

実験で %LOOKUPの直前に N の値を変更しておいても
検索の開始位置としての影響はない。
いちいち 開始意図を指定するのは面倒であるが
OS Ver7.1 でこの障害が出てしまったので
参考までに公開した。
_

[参考RPGソース: TESTLOOK]

ソースはこちらから

001.00 H DFTNAME(TESTLOOK) DATEDIT(*YMD/) BNDDIR('QC2LE') DFTACTGRP(*NO)                             
002.00 F********** %LOOKUP のテスト *************************************                            
003.00 F*                                                                                            
004.00 F*****************************************************************                            
005.00                                                                                               
006.00  *( 作業変数の定義 )                                                                          
007.00 D N               S              4S 0                                                         
008.00 D RECR            S             10A   DIM(32)                               レコード名の配列  
009.00 D RC              S              4S 0                                       配列数            
010.00 D MSG             S             40A                                                           
011.00 D ANS             S              1A                                                           
012.00                                                                                               
013.00  /FREE                                                                                        
014.00    N = 4;                                                                                     
015.00    N = %LOOKUP('PRTHEAD   ': RECR);                                                           
016.00    IF N > 0;                                                                                  
017.00      MSG = 'FOUND AT ' + %CHAR(N);                                                            
018.00    ELSE;                                                                                      
019.00      MSG = 'NOT FOUND';                                                                       
020.00    ENDIF;                                                                                     
021.00    DSPLY MSG '' ANS;                                                                          
022.00    *INLR = *ON;                                                                               
023.00  /END-FREE                                                                                    
0024.00  ***********************************************************                              
0025.00 C     *INZSR        BEGSR                                                  * 初期値セット 
0026.00  ***********************************************************                              
0027.00  /FREE                                                                                    
0028.00    RECR(1) = 'PRTHEAD   ';                                                                
0029.00    RECR(2) = 'MIDDTA    ';                                                                
0030.00    RECR(3) = 'DETAIL    ';                                                                
0031.00    RECR(4) = 'PRTENDD   ';                                                                
0032.00    RC = 4;                                                                                
0033.00  /END-FREE                                                                                
0034.00 C                   ENDSR     


                                                             

[コンパイル]

CRTBNDRPG PGM(OBJLIB/TESTLOOK) SRCFILE(SRCLIB/QRPGLESRC) DFTACTGRP(*NO
) ACTGRP(*NEW) DBGVIEW(*SOURCE) AUT(*ALL)