CL

163. CLPの%SCAN の使い方

Ver7.1から文字列の検索は組込み関数: %SCAN が使えるようになっている。
弊社の開発機もそれまでのVer6.1からVer7.1に変更になったので
%SCAN が使えるようになった。
それまでの文字列検索はAPI: QCLSCAN を使わなければななかったが
QCLSCANの使用は大げさであり小さな文字列の検索でも
大規模な用意の手間を必要としていた。
 _

■ QCLSCAN と %SCAN の比較

 ろ 
最初にQCLSCAN と %SCAN の違いを説明しよう。
 

[例] 変数 &VALUE の中に「SELECT」という文字列があるかをQCLSCAN を使って調べる

0136.00  /*( QCLSCAN のための変数 )*/                                      
0137.00              DCL        VAR(&KWD) TYPE(*CHAR) LEN(48)              
0138.00              DCL        VAR(&KWS) TYPE(*CHAR) LEN(10) VALUE('/')   
0139.00              DCL        VAR(&KWSLEN) TYPE(*DEC) LEN(3 0) VALUE(1)  
0140.00              DCL        VAR(&KWDLEN) TYPE(*DEC) LEN(3 0) VALUE(10) 
0141.00              DCL        VAR(&STWLEN) TYPE(*DEC) LEN(3 0) VALUE(128)
0142.00              DCL        VAR(&VALLEN) TYPE(*DEC) LEN(3 0) VALUE(128)
0143.00              DCL        VAR(&RESULT) TYPE(*DEC) LEN(3 0)           
0144.00              DCL        VAR(&STRPOS) TYPE(*DEC) LEN(3 0) 
    :                 :
0290.00              CALL       PGM(QCLSCAN) PARM(&VALUE &STRLEN &STRPOT +        
0291.00                           'SELECT' &SLTLEN ' ' ' ' ' ' &RESULT)           
0292.00              IF         COND(&RESULT *GT 0) THEN(DO) /* SELECT SQL あり */
  :                       :
0297.00              ENDDO      /* SELECT SQL あり  */

[解説]

文字列の入った変数: &VALUE の長さは &STRLEN であり &VALUEの開始位置 &STRPOT から
‘SELECT’ という長さ &SLTLEN の文字列を検索して見つかれば &RESULT に見つかった位置が
戻される。見つからなければ &RESULT は 0 である。

[例] 変数 &VALUE の中に「SELECT」という文字列があるかを %SCAN を使って調べる

0136.00  /*( %SCAN のための変数 )*/                                         
0137.00              DCL        VAR(&KWD) TYPE(*CHAR) LEN(48)               
0138.00              DCL        VAR(&KWS) TYPE(*CHAR) LEN(10) VALUE('/')    
0139.00              DCL        VAR(&VALLEN) TYPE(*DEC) LEN(3 0) VALUE(128) 
0140.00              DCL        VAR(&RESULT) TYPE(*DEC) LEN(3 0)            
  :
0285.00              CHGVAR     VAR(&RESULT) VALUE(%SCAN('SELECT' &VARDTA))       
0286.00              IF         COND(&RESULT *GT 0) THEN(DO) /* SELECT SQL あり */
  :                     :
0291.00              ENDDO      /* SELECT SQL あり  */

[解説]

%SCANによって変数 &VALUEの中から ‘SELECT’の文字列を探して見つかれば
&RESULT にはその位置が戻され見つからなければ &RESULT は 0となる。
  
    ご覧のように QCLSCANに比べて%SCANの使用はとてもシンプルでわかりやすくなる。
QCLSCANでは探す対象となる変数の長さ:&STRLEN と探す文字列の長さ: &SLTEN を
制限しなければならないので冗長となってしまう。
もしそれらの長さの指定を誤るとQCLSCANは正常に動作しないので
ばぐが発生する要因となってしまう。

現在、大半のIBMユーザーはVer7.2以降で運営しているはずなので
ほとんどが%SCANの使用が可能である。
%SCANにするといかにシンプルでバグの発生する可能性も低くなるみとは間違いない。

■ %SCANの使用例

 

(1)見つかった位置を特定する %SCANの使い方

    CHGVAR     VAR(&RESULT) VALUE(%SCAN('SELECT' &VARDTA))

-> &VARDTAの中から ‘SELECT’という文字列を探して見つかった位置を &RESULT として戻す。

(2)文字列があるかだけを判定する %SCANの使い方

    IF (%SCAN('SELECT' &VARDTA) > 0) THEN(DO)
        :
    ENDDO

-> &VARDTA の中に ‘SELECT’という文字列が含まれているかどうかだけを検査している。

 

(3)任意の文字列 &KWDが含まれているかどうかを検査する %SCANの使い方

     CHGVAR VAR(&KWD) VALUE(%TRIMR(&KWD))
     IF (%SCAN('SELECT' &VARDTA) > 0) THEN(DO)
        :
     ENDDO

–>文字列を含む変数 &KWD は探索する前に %TRIMR によって右側の後続するブランクを
消去しておかなければならない。
IBM が &SCANと同時に %TRIM や %TRIMR も同時にリリースしているのは
このためであろう。
この %TRIMR を使うことが今回紹介したテクニックの最も重要な部分であり
もちろんこのことはIBMマニュアルには紹介されていない。

※ %SCAN, %TRMR は Ver7.1 のPTFとして追加されたので Ver7.1のIBMマニュアルの中を
探しても%SCAN, %TRIMRの説明は見つからない。
   %SCAN, %TRIMRはPTFとして追加されているが PTFの %SCAN, %TRIMR によって開発されたプログラムは
Ver5.4, 6.1, 7.1 ~で有効に動作することがIBMによって保証されている。
_