読者です 読者をやめる 読者になる 読者になる

タイガー!タイガー!じれったいぞー!(SE編)

AS400,WAS,GlassFish,Java,JavaEE,JSF等の開発における日々の気づきをまとめたブログ(備忘録)。

【AS400】RPGLE-文字列に半角¥が含んでいるかの判定処理

表題の処理をどうしてもやりたくて、BIF関数等をいろいろと試したのですが、うまくいかず。。。

さすがは、アメリカ産まれのAS400! そうは問屋は卸してくれませんね。

具体的には、%SCANを使って、半角¥の文字位置を取得しようとしたのですが、全角¥でも位置を拾ってきてしまうことがわかりました。
理由は、EBCDIC文字コードの16進数で比較しているとのこと。

     D MAIN            PR                  EXTPGM('SAMPLE34')
     D MAIN            PI                                    
     D*                                                      
     D W@STR1          S             20                      
     D W@STR2          S             20                      
     D*                                                      
      /FREE                                                  
          W@STR1 = '\';     // 半角¥                               
          W@STR2 = ' ¥ ';  // 全角¥                           
                                                             
          DSPLY %CHAR(%SCAN('\':W@STR1)); // 結果 = 1   
          DSPLY %CHAR(%SCAN('\':W@STR2)); // 結果 = 3        
                                                             
          *INLR = *ON;                                       
          RETURN;                                            
      /END-FREE                                              

SCAN関数の結果がゼロならば、含んでいないという判定をしようと計算していたのですが、これは使えません。

文字コードを見てみると、半角だろうが、全角だろうが、文字¥を16進数「5B」が含んでいるので正しい結果といえそうです。

半角¥・・・X'5B'
全角¥・・・X'0E425B0F'   // 英数字および関連記号 (42 区)

ということで、自作することにしました。 文字列を1つずつ調査し、シフト文字の範囲内は無視し、それ以外で16進数「5B」が存在する場合に、半角¥ありという判定としました。

     D MAIN            PR                  EXTPGM('SAMPLE35')
     D                               20  
     D                                1A
     D MAIN            PI 
     D  P@NSTR                       20
     D  P@FRTN                        1A
     D*               
     D ARRDS           DS 
     D  ARR                           1A   DIM(64)
     D W@CHECK         S              1N
     D W@0E            S              1A   INZ(X'0E')
     D W@0F            S              1A   INZ(X'0F') 
     D W@HYEN          S              1A   INZ(X'5B')
     D I               S              2S 0
     D*          
      /FREE 
           P@FRTN = *OFF; 
           W@CHECK = *ON; 
           ARRDS = P@NSTR;  
                    
           FOR I = 1 TO %CHECKR(' ':P@NSTR);
               SELECT;
                   WHEN ARR(I) = W@0E; 
                       W@CHECK  = *OFF; 
                   WHEN ARR(I) = W@0F;
                       W@CHECK  = *ON; 
                   WHEN ARR(I) = W@HYEN;
                       IF W@CHECK = *ON;
                           P@FRTN = *ON;
                           LEAVE;
                       ENDIF;
                   OTHER;
               ENDSL;
           ENDFOR;
                
           *INLR = *ON;
           RETURN;
      /END-FREE             

日本人に産まれて超ハッピー!なのですが、こういうときは、ちょっと英語圏の方がうらやましく思ってしまいますよ。。。