4
0

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)の自己学習メモ06 CLプログラム(Control Language) Part4

Last updated at Posted at 2020-04-07

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

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

概要

CLプログラムサンプルをため込んでいこうの第2弾。

CLサンプルプログラム

*DEC型を利用した計算

DCLで定義する際のTYPEに指定するデータ型で、*DECを利用した際の計算処理の結果を出力するサンプルです。
ちなみに、*DECはIBMのサイトで以下のように説明されていました。

パック10進数値を含む10進変数。

参考:https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/cl/dcl.htm#DCL.TYPE

自分が無知なんだと思うのですが、何言ってんのかよくわかりませんでした。
Javaなどのプログラミング言語の経験はあるので、イメージとしては小数点を含んだ数値を扱うことのできる、floatやdoubleの位置付けに近いものかなと思っています。

ただ、LEN(n m)と、全体の桁数と小数点の桁数を指定しなければならず、Oracleのnumber型と定義の方法が似ているので、そんな感じかなと思っています。

PGM
 FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
        *************** Beginning of data ******************************************************************
0001.00              PGM                                                                                    
0002.00              DCL        VAR(&PRICE) TYPE(*DEC) LEN(10 0) VALUE(158)                                 
0003.00              DCL        VAR(&TAX) TYPE(*DEC) LEN(3 2) VALUE(0.10)                                   
0004.00              DCL        VAR(&AMOUNT) TYPE(*DEC) LEN(12 2)                                           
0005.00 START:                                                                                              
0006.00              CHGVAR     VAR(&AMOUNT) VALUE(&PRICE + &PRICE * &TAX)                                  
0007.00              SNDPGMMSG  MSG('The calculation result is' *BCAT +                                     
0008.00                           %CHAR(&AMOUNT))                                                           
0009.00              RETURN                                                                                 
0010.00 END:                                                                                                
0011.00              ENDPGM                                                                                 
        ****************** End of data *********************************************************************
出力結果
The calculation result is 173.80

*INT型を利用した計算

DCLで定義する際のTYPEに指定するデータ型で、*INTを利用した際の計算処理の結果を出力するサンプルです。
*INTはIBMのサイトで以下のように説明されていました。

符号付き2進値を含む整変数。

参考:https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/cl/dcl.htm#DCL.TYPE

*DECよりはまだなんとなく分かる。。。
整変数→整数なんでしょ?小数点を扱わない数値型なんでしょ?という感じ。

計算は*DECのサンプルと同じ数値を利用して計算しているため、出力結果として173.80173に丸められて出ているのが分かる。
特に意識しない場合、小数点以下の数値は切り捨てられるんですね。

%DECHという組み込み関数を使うことで、四捨五入ができるような記事があるのですが、
これってCLだと使えないんでしょうか?
CLだと四捨五入ってどうやるんだろう・・・

PGM
 FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 
        *************** Beginning of data *******************************************************************
0001.00              PGM                                                                                     
0002.00              DCL        VAR(&PRICE) TYPE(*DEC) LEN(10 0) VALUE(158)                                  
0003.00              DCL        VAR(&TAX) TYPE(*DEC) LEN(3 2) VALUE(0.10)                                    
0004.00              DCL        VAR(&AMOUNT) TYPE(*INT)                                                      
0005.00 START:                                                                                               
0006.00              CHGVAR     VAR(&AMOUNT) VALUE(&PRICE + &PRICE * &TAX)                                   
0007.00              SNDPGMMSG  MSG('The calculation result is' *BCAT +                                      
0008.00                           %CHAR(&AMOUNT))                                                            
0009.00              RETURN                                                                                  
0010.00 END:                                                                                                 
0011.00              ENDPGM                                                                                  
        ****************** End of data **********************************************************************
出力結果
The calculation result is 173

IF/ELSE IFの条件分岐

ELSE IFの書き方としては2パターンあるようで、F4キーを押下してコードを自動保管し、整形してしまうとPattern1のようなごちゃごちゃしたコードになってしまう。
こういうときは、行コピー&ペーストでIF文をコピーして、その左側にELSEを添えてあげ、F4キーに頼らないようにすれば、少し見やすいコードになる。

PGM
 FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
        *************** Beginning of data ******************************************************************
0001.00              PGM                                                                                    
0002.00              DCL        VAR(&PWD) TYPE(*CHAR) LEN(10) VALUE('Pwd01')                                
0003.00              DCL        VAR(&DIV) TYPE(*CHAR) LEN(1) VALUE('3')                                     
0004.00 START:                                                                                              
0005.00 /* IF ELSE */                                                                                       
0006.00              SNDPGMMSG  MSG('Section IF ELSE')                                                      
0007.00              IF         COND(&PWD = 'Password01') THEN(DO)                                          
0008.00              SNDPGMMSG  MSG('Success!')                                                             
0009.00              ENDDO                                                                                  
0010.00              ELSE       CMD(DO)                                                                     
0011.00              SNDPGMMSG  MSG('Fail')                                                                 
0012.00              ENDDO                                                                                  
0013.00 /* IF ELSE IF Pattern1 */                                                                           
0014.00              SNDPGMMSG  MSG('Section IF ELSE IF Pattern1')                                          
0015.00              IF         COND(&DIV = '1') THEN(SNDPGMMSG MSG('Div1'))                                
0016.00              ELSE       CMD(IF COND(&DIV = '2') THEN(SNDPGMMSG +                                    
0017.00                           MSG('Div2')))                                                             
0018.00              ELSE       CMD(IF COND(&DIV = '3') THEN(SNDPGMMSG +                                    
0019.00                           MSG('Div3')))                                                             
0020.00 /* IF ELSE IF Pattern2 */                                                                           
0021.00              SNDPGMMSG  MSG('Section IF ELSE IF Pattern2')                                          
0022.00              IF         COND(&DIV = '1') THEN(SNDPGMMSG MSG('Div1'))                                
0023.00         ELSE IF         COND(&DIV = '2') THEN(SNDPGMMSG MSG('Div2'))                                
0024.00         ELSE IF         COND(&DIV = '3') THEN(SNDPGMMSG MSG('Div3'))                                
0025.00              RETURN                                                                                 
0026.00 END:                                                                                                
0027.00              ENDPGM                                                                                 
        ****************** End of data *********************************************************************
出力結果
Section IF ELSE             
Fail                        
Section IF ELSE IF Pattern1 
Div3                        
Section IF ELSE IF Pattern2 
Div3                        

ちなみに、ここでは比較演算子として=(イコール)記号を利用しているが、以下のような記号ではない指定の方法もあるので、どちらかを指定する。(コーディングルールに準拠する。)

事前定義値 事前定義記号 意味
*EQ = 等しい
*GT > より大きい
*LT < より小さい
*GE >= より大きいまたは等しい
*LE <= より小さいまたは等しい
*NE ¬= 等しくない
*NG ¬> より大きくない
*NL ¬< より小さくない

参考:https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rbam6/rbam6opsinexp.htm

SELECT条件分岐

switch文のような条件分岐を実現する方法についてサンプルを作成。

PGM
 FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
        *************** Beginning of data ******************************************************************
0001.00              PGM                                                                                    
0002.00              DCL        VAR(&DIV) TYPE(*CHAR) LEN(1) VALUE('3')                                     
0003.00              SELECT                                                                                 
0004.00              WHEN       COND(&DIV *EQ '1') THEN(SNDPGMMSG MSG('Div1'))                              
0005.00              WHEN       COND(&DIV *EQ '2') THEN(SNDPGMMSG MSG('Div2'))                              
0006.00              WHEN       COND(&DIV *EQ '3') THEN(SNDPGMMSG MSG('Div3'))                              
0007.00              OTHERWISE  CMD(SNDPGMMSG MSG('Div other'))                                             
0008.00              ENDSELECT                                                                              
0009.00              ENDPGM                                                                                 
        ****************** End of data *********************************************************************
出力結果
Div3                        

繰り返し処理

IFとラベル(GOTO)を利用した繰り返し処理

PGM
 FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
        *************** Beginning of data ******************************************************************
0001.00              PGM                                                                                    
0002.00              DCL        VAR(&NUM1) TYPE(*INT) VALUE(1)                                              
0003.00              SNDPGMMSG  MSG('Start IF loop')                                                        
0004.00  LOOP1:      IF         COND(&NUM1 <= 3) THEN(DO)                                                   
0005.00              SNDPGMMSG  MSG('The number is' *BCAT %CHAR(&NUM1))                                     
0006.00              CHGVAR     VAR(&NUM1) VALUE(&NUM1 + 1)                                                 
0007.00              GOTO       CMDLBL(LOOP1)                                                               
0008.00              ENDDO                                                                                  
0009.00              SNDPGMMSG  MSG('End IF loop')                                                          
0010.00              ENDPGM                                                                                 
        ****************** End of data *********************************************************************
出力結果
Start IF loop
The number is 1
The number is 2
The number is 3
End IF loop

DOWHILEを利用した繰り返し処理

DOWHILEは、CONDの条件がTRUEの間繰り返し処理をする。

PGM
 FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
        *************** Beginning of data ******************************************************************
0001.00              PGM                                                                                    
0002.00              DCL        VAR(&NUM1) TYPE(*INT) VALUE(1)                                              
0003.00              SNDPGMMSG  MSG('Start Do While')                                                       
0004.00              DOWHILE    COND(&NUM1 <= 3)                                                            
0005.00              SNDPGMMSG  MSG('The number is' *BCAT %CHAR(&NUM1))                                     
0006.00              CHGVAR     VAR(&NUM1) VALUE(&NUM1 + 1)                                                 
0007.00              ENDDO                                                                                  
0008.00              SNDPGMMSG  MSG('End Do While')                                                         
0009.00              ENDPGM                                                                                 
        ****************** End of data *********************************************************************
出力結果
Start Do While  
The number is 1 
The number is 2 
The number is 3 
End Do While    

DOFORを利用した繰り返し処理

PGM
 FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
        *************** Beginning of data ******************************************************************
0001.00              PGM                                                                                    
0002.00              DCL        VAR(&NUM1) TYPE(*INT) VALUE(1)                                              
0003.00              SNDPGMMSG  MSG('Start For')                                                            
0004.00              DOFOR      VAR(&NUM1) FROM(1) TO(3)                                                    
0005.00              SNDPGMMSG  MSG('The number is' *BCAT %CHAR(&NUM1))                                     
0006.00              ENDDO                                                                                  
0007.00              SNDPGMMSG  MSG('End For')                                                              
0008.00              ENDPGM                                                                                 
        ****************** End of data *********************************************************************
出力結果
Start For
The number is 1 
The number is 2 
The number is 3 
End For    
4
0
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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?