自己学習メモインデックス
概要
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型と定義の方法が似ているので、そんな感じかなと思っています。
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.80
が173
に丸められて出ているのが分かる。
特に意識しない場合、小数点以下の数値は切り捨てられるんですね。
%DECH
という組み込み関数を使うことで、四捨五入ができるような記事があるのですが、
これってCLだと使えないんでしょうか?
CLだと四捨五入ってどうやるんだろう・・・
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キーに頼らないようにすれば、少し見やすいコードになる。
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文のような条件分岐を実現する方法についてサンプルを作成。
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)を利用した繰り返し処理
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の間繰り返し処理をする。
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を利用した繰り返し処理
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