CLプログラム 
目 次

このページではコマンド言語(CL)プログラムを紹介します。
CLプログラムは、一連のコマンドによる処理手順をプログラムにしたものです。
定型化した処理手順をCLプログラムにすることによって、処理の操作量とミスを大幅に減少することができます。
また、CLプログラムはサブ・プログラムとしてRPGやCOBOLなどから呼び出しすることもできます。




1.簡単な例

たとえば、PGM1とPGM2を連続して実行するような場合、CLでは次のように記述します。

PGM     
             CALL       PGM(PGM1) 
             CALL       PGM(PGM2) 
ENDPGM   


2.CLプログラムの構成


一般型

CLプログラムの一般形は、PGMで始まり、ENDPGMでおわります。

PGM  PARM(パラメータリスト)

DCLF ファイルの定義
DCL 変数名の定義

CLコマンド1
CLコマンド2
・ ・ ・
ENDPGM


パラメータリストがないときはPARM以下省略できます。また、CLプログラムでファイルを使用しないときは、ファイルの定義を省略できます。さらに、変数を使用しないときは、変数の定義を省略できます。文法的に最小限必要なのは上記網掛け部分のみです。
以下にPGM01、PGM02、PGM03を連続実行するCLプログラムの例を紹介ます。

CLP01: PGM
    CALL PGM01 /* AAA 処理 */
    CALL PGM02 /* BBB 処理 */
    CALL PGM03 /* CCC 処理 */
ENDPGM


コマンド文


プログラムはいくつかのコマンド文からなります。コマンドは一般に次の形をしています。

ラベル:コマンド  キーワード1(パラメータ1) キーワード2(パラメータ2) …

ラベルはGOTOで実行の順を変えるときの飛び先です。コロンで区切ります。
コマンドは機能を実行する命令で、コマンド選択命令、

  SLTCMD *ALL

で表示させることができます。
キーワード1,2、…は、各コマンドで決まっているパラメータのためのキーワードです。
キーワードは、コマンド+F4キーでプロンプト画面を表示させておき、さらにF11キーを押すと確認できます。
CRTCLPGMコマンドでの例を紹介ます。

                          CL プログラム作成  (CRTCLPGM)                        
                                                                               
  選択項目を入力して,実行キーを押してください。                               
                                                                               
  プログラム  . . . . . . . . . . PGM          > CLPGM01                       
    ライブラリー  . . . . . . . .              >   WRKLIB                      
  ソース・ファイル  . . . . . . . SRCFILE        QCLSRC                        
    ライブラリー  . . . . . . . .              >   WRKLIB                      
  ソース・メンバー  . . . . . . . SRCMBR         *PGM                          
  テキスト ' 記述 ' . . . . . . . TEXT           *SRCMBRTXT                    
                                                                               

コマンドが1行におさまらないときは、以下のように'+'記号で、区切りのブランクを挿入可能なところでコマンドを分割して行をわけることができます。

CRTCLPGM PGM(WRKLIB/CLPGM01) +
          SRCFILE(WRKLIB/QCLSRC)


パラメータの順が正しいときは、以下のようにキーワードの省略することもできます。

CRTCLPGM WRKLIB/CLPGM01 WRKLIB/QCLSRC


注釈

注釈は、/*で始まり*/で終わる形の文字列です。区切りとしてのブランクが置けるところなら、
どこにでも置けます。
例えば下記のように、CALLの前後、PGMパラメータの後におくことができます。

    /* 処理手順1 */  CALL  /* 今回特別処理 */  +
          PGM(PGM3)  /* 必要データ抜き出し */


ファイルの定義

CLでファイルを使用する場合には、DCLFコマンドでファイルの宣言をします。
このコマンドはCLプログラムでのみ使用可能で、会話型のコマンドとしては使用できません。
例えば、以下のような画面(MNU01S)で選択した番号により、PGM01、02、03、05を呼出すメニューの
例でCLプログラムの例を紹介します。

                  受発注処理                           
                                                       
  番号を入力して下さい ==> B                           
                                                       
   1. 受注処理                                         
   2. 仕入発注処理                                     
   3. 在庫受払処理                                     
                                                       
   5. マスター保守                                     
                                                       
                                                       
                                                       
                                                       
                                                       
                                                       
                                                       
                                                       
                                                       
 F3= 終了                                              
 メニュー番号誤り

画面のDDSは次のように準備されているものとします。
     A*--------------------------------------------------------------- 
     A* ID   : MNU01S                                                  
     A* NAME : 受発注処理                                              
     A*--------------------------------------------------------------- 
     A          R MNU01                     TEXT(' 受発注処理   ')     
     A                                      CF03(03)                   
     A* FIELD                                                          
     A                                  1 18' 受発注処理 '             
     A                                  3  2' 番号を入力して下さい ==>'
     A            S1MNU          1A  B    +1TEXT(' 選択番号 ')         
     A                                  5  4'1. 受注処理 '             
     A                                  6  4'2. 仕入発注処理 '         
     A                                  7  4'3. 在庫受払処理 '         
     A                                  9  4'5. マスター保守 '         
     A                                 23  2'F3= 終了 '                
     A  30                             24  2' メニュー番号誤り '       

MNU01はレコード様式のID,S1MNUは画面のフィールド名、プログラムの中では変数となります。
同じ行、1Aは1桁の英数字を意味します。
最後の30は’メニュー番号誤り’の文字列を表示させるための標識で、表示させるときのみオンにします。
プログラムで使用するファイルの宣言はつぎのようにします。

DCLF  FILE(ファイル名)

ファイル名は上記の画面ではMNU01Sになります。実際にはレコード様式の指定をするパラメータ
RCDFMTがあるのですが、省略すると*ALLとなり、99件までの様式をすべて定義してくれるので省略します。
DCLFコマンドは実行コマンドより先になければなりません。


変数の定義

CLプログラムで使用する変数名には、外部ファイルで定義された変数名と、CLプログラム内部で定義された
変数名とがあります。いずれも&CCCCの形をしており、&を含めて11桁までの長さです。

外部定義の変数名

DCLFでファイルを宣言した場合、そのファイルで定義されているフィールドはCLプログラムで使用できるように
なります。
先のメニュー画面ではS1MNUというフィールドが定義されているので、CLプログラムでは、&S1MNUという
名称で使用できます。
標識の場合は、&INnnの形です。先の例ではF3キーが標識03に関連づけられて定義されているので、
CLプログラムの中では&IN03という変数名で使用でます。

プログラム定義の変数名

プログラム内部で変数を定義するときは、DCLコマンドで定義します。
定義できるデータタイプは、文字列、パック10進数、論理値の3種です。定義はそれぞれ次のようにします。
CLの変数は1桁目が&、2桁目が英字の、全11桁までの英数字からなる文字列で、DCL命令により、
明示的に記述します。

変数の属性としては、*CHAR, *DEC *LGLの3種類があります。

DCL  VAR(&PGID)      TYPE(*CHAR)  LEN(10)   /* 文字列データ */
DCL  VAR(&OUTRECS)   TYPE(*DEC)   LEN(9 0)  /* 数値データ */
DCL  VAR(&SW)       TYPE(*LGL)   LEN(1)    /* 論理データ */





評価したとき、最終的にある値を表わすものを式といいます。式の例を示します。
  &A || 'XYZ'        連結演算。&Aは*CHARとします。
  &B * 10        掛け算。&Bは*DECとします。
  &C | &D        論理演算(or)。&C、&Dともに*LGLとします。

定数も式の1種です。


関数


関数はある値を与えたとき、それを加工して別の値を返すものを言います。
ここでは文字列の一部取出し関数%SUBSTRINGのみ紹介します。省略形は%SSTです。
一般形は次のとおりです。

%SUBSTRING(変数名  開始位置  長さ)

例えば、変数&Aが'ABCDEFGHIJ'としたとき、

%SUBSTRING(&A  5  3)

は、'EFG'をかえします。

疑似変数

%SUBSTRING(省略形%SST)を逆方向に使用して、みかけ上の変数として使用できます。例えば、

%SUBSTRING(&A  5  3)

は、&Aの5桁目から3バイトを占めるみかけ上の変数になります。
&Aが'ABCDEFGHIJ'として、この擬似変数に'XYZ'をセットすると、'ABCDXYZHIJ'になります。

例:
    DCL   VAR(&A)   TYPE(*CHAR)   LEN(8)  VALUE( '12345678')
    CHGVAR  VAR(%SST(&A 3 2))  VALUE('AB')


%SSTは指定の文字列から任意の桁数だけ取り出す関数ですが、これを逆の操作に使って、
この例では、文字列&Aの3桁目から2桁だけ(とりだすのでなく)'AB'をセットします。
文字列は
    '12AB5678'
になります。
     


変数の内容の変更

変数の変更はCHGVARコマンドで行います。
この命令はCLプログラムの中だけで使用できる命令です。
一般型は次のとおりです。

    CHGVAR  VAR(変数名)  VALUE(式)

変数名はDCL、あるいは外部記述でで定義されたものです。
式とは評価したとき、最終的にある値を表すものをいいます。以下に例をいくつか示します。
例:
    CHGVAR  VAR(&LINES)      VALUE(&COUNT + 12)
    CHGVAR  VAR(&ERRMSG)    VALUE(' 正しい番号を入力して下さい ')
    CHGVAR  VAR(&SW)        VALUE(*ON)
    CHGVAR  VAR(%SST(&A 3 2))  VALUE('AB')

演算子

式で使用できる演算子には次のようなものがあります。
  +   加算
  −   減算
  *   乗算
  /   除算
  ||   連結演算(文字列を連結します。)
  *LT(または <)
  *LE(または <=)
  *EQ(または =)
  *GE(または >=)
  *GT(または >)
  *NE(または¬=)
  *AND(または &)
  *OR(または |)
  *NOT(または¬)


実行の制御(分岐)

プログラム実行は上から順に行われます。実行順を変更制御するには、IF,GOTO,SELECT,CALLなどの
命令があります。
GOTOは無条件に実行先を変更します。一般形は次のとおりです。

GOTO   飛び先ラベル

条件によって実行を制御するコマンドはIFです。IFの一般形は次のとおりです。ENDIFはありません。

IF COND(条件式) THEN(コマンド)

条件式は、最終的に論理演算結果をあらわすものでなければなりません。
条件式が真のとき、THENで与えられたコマンドを実行します。

IF  COND(&A= &B)  THEN(GOTO  CMDLBL(NEXT99))

条件式が偽のときに実行するコマンドはELSEで指定します。

ELSE  CMD(CALL  PGM(AAA))

THENあるいはELSEの実行範囲を拡張するには、以下のようにDOとENDDOのコマンドで
DOグループを形成して拡張します。ENDIFはないので注意して下さい。

        IF  COND(&A = &B)  THEN(DO)
                CALL  PGM(PGM1)
                CALL  PGM(PGM2)
        ENDDO
        ELSE  CMD(DO)
                CALL  PGM(PGM3)
                CALL  PGM(PGM4)
        ENDDO


ケース処理

いくつかのケースにより処理をする場合は、SELECTを使用します。一般形は次の通りです。

SELECT

WHEN COND(条件式1)

  実行命令グループ1

WHEN COND(条件式2)

  実行命令グループ2

  ・・・

OTHERWISE

  実行命令グループn

ENDSELECT



繰り返しの制御

繰り返し実行させるための命令には、DOWHILEとDOUNTILがあります。
いずれの場合もENDDOまでの一連の命令を実行させます。

DOWHILE COND(条件式)

条件が成立している間実行します。

 
        DOWHILE  COND(&A = &B)  
                CALL  PGM(PGM1)
                CALL  PGM(PGM2)
        ENDDO
        


DOUNTIL COND(条件式)

条件が成立するまで実行します。

 
        DOUNTIL  COND(&A = &B)  
                CALL  PGM(PGM1)
                CALL  PGM(PGM2)
        ENDDO
        


繰り返しのバイパス

ITERATE

DOグループでそのENDDOまでの処理をバイパスします。

 
      DOUNTIL  COND(&A = &B)                        
        IF         COND(&A = '1') THEN(ITERATE)     
             CALL  PGM(PGM1)                        
             CALL  PGM(PGM2)                        
      ENDDO                                         
        








この例では&Aが’1’のとき、PGM1,PGM2の呼び出しはバイパスされます。


繰り返しからの脱出

LEAVE

DOグループでそのENDDOまでの処理をバイパスします。

   DOUNTIL  COND(&A = &B)                   
    IF         COND(&A = '1') THEN(LEAVE)  
         CALL  PGM(PGM1)                   
         CALL  PGM(PGM2)                   
   ENDDO                                    
        









この例では&Aが’1’のとき、DOグループを脱出します。


外部プログラムの呼び出し

外部のプログラムに実行を渡すときは、CALLコマンドを使用します。
CALLコマンドはPGMパラメータであたえたプログラムに制御を移します。
PARMパラメータで引数の授受ができます。制御を移したプログラムが終了すると、
CALLの次のコマンドから実行を継続します。

      CALL  PGM(PGM2)  PARM(&DATA1  X'0123456F')


ファイル入出力

画面ファイルの入出力は、SNDRCVF(send recieve format)で行います。次のように使用します。

SNDRCVF  RCDFMT(レコード様式名)


これにより、DCLFで定義したファイルに表示データを送り、入力されたデータを取得します。

画面ファイル/DBファイルからの入力は、RCVFで行います。次のように使用します。

RCVF  RCDFMT(レコード様式名)

これにより、DCLFで定義したファイルからデータを取得します。以下に例を示します。
(この例は無限の繰返しになっています。)

PGM       
             DCLF       FILE(M420)          
MORE:        RCVF       RCDFMT(M420R) 
             SNDPGMMSG  &TKNAME             
             GOTO       CMDLBL(MORE)        
END:         ENDPGM    

画面ファイルへの出力はSNDFで行います。表示装置ファイルだけに出力できます。
SNDFでDBファイルへ出力することはできません。

エラーの処理

エラーメッセージが発行された場合、それをモニターしてシステムに代わって処理をするには、
MONMSGコマンドを使用します。例えば、RCVFコマンドでDBファイルがEOF(end of file)になったとき、
エラーメッセージが発行されます。これをモニターして、代わりにGOTOコマンドを実行するときは
次のようにします。

PGM                                                              
             DCLF       FILE(M420)                               
MORE:        RCVF       RCDFMT(M420R)                            
             MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(END))    
             SNDPGMMSG  MSG(&TKNAME)                             
             GOTO       CMDLBL(MORE)                             
END:         ENDPGM                        

この例では、データベースを読みとり、EOFのときCPF0864のエラーになるので、
これをモニターしています。

複数のエラーメッセージに対応するには、

MONMSG MSGID(CPF2105  CPF2802)・・・・

のようにMSGIDパラメータで複数のMSGIDをあたえます。
MONMSGにEXECパラメータをつけないと、エラーメッセージが発行されても何の処理を行いません。
どのようなエラーメッセージ(CPFXXXX)が発行されてもモニターするには、MSGIDをCPF0000のようにします。
以下に例をしめします。

PGM                                                       
             DLTF       FILE(QTEMP/TESTPF)                
             MONMSG     MSGID(CPF0000)                    
             CRTPF      FILE(QTEMP/TESTPF) RCDLEN(40)     
ENDPGM                                                   

この例では、ファイル削除のDLTFが正常に行われても、失敗しても差し支えないので、発行される
エラーメッセージを無視するようにしています。

CLでのパラメータの授受

CLでパラメータを授受するにはCLの最初のPGM文でPARMパラメータを使用します。
以下に例をしめします。

PGM PARM(&P@BMCD  &P@DATE)
DCL  &P@BMCD  *CHAR  10
DCL  &P@DATE   *DEC   8


この例では、呼出側から10桁の文字列を&P@BNCDで、8桁の日付を&P@DATEで授受しています。

サンプル

CLプログラムのサンプルを示します。

朝一番プログラム

1日の業務の開始にあたって実行する処理の例です。
このCLプログラムでは、物理ファイル再編成、当日日付のセット、定時開始プログラムの投入など
適当な想定のもとに処理をしています。

PGM                                                                     
             DCL        VAR(&FLD1) TYPE(*CHAR) LEN(200)                 
             DCL        VAR(&CYMD) TYPE(*CHAR) LEN(7)                   
/* ジョブ日付の取得とユーザーデータエリアへの格納 */ 
             RTVJOBA    CYMDDATE(&CYMD)                                 
             DLTDTAARA  DTAARA(WRKLIB/AREA1)    /* ユーザーデータエリア削除 */  
             MONMSG     MSGID(CPF2105)          /* エラー回避 */
             CRTDTAARA  DTAARA(WRKLIB/AREA1) TYPE(*CHAR) LEN(200)       
             CHGVAR VAR(&FLD1)      VALUE(&CYMD)                        
             CHGDTAARA  DTAARA(WRKLIB/AREA1 (1 7)) VALUE(&FLD1)         
/* ファイル再編成  */ 
             RGZPFM     FILE(WRKLIB/F510)   /*  受注見出しファイル   */
             RGZPFM     FILE(WRKLIB/F520)   /*  受注明細ファイル     */  
             RGZPFM     FILE(WRKLIB/F610)   /*  仕入見出しファイル   */
             RGZPFM     FILE(WRKLIB/F620)   /*  仕入明細ファイル     */
/* 仮OUTQのクリア  */    
             CLROUTQ    OUTQ(QPRINT9)       /* TEMP-OUTQ      */        
/*  定時開始ジョブの投入  */ 
             SBMJOB   CMD(CALL PGM(PGM1A)) SCDTIME(093000) /*  9:30 */ 
             SBMJOB   CMD(CALL PGM(PGM2A)) SCDTIME(121000) /* 12:10 */ 
             SBMJOB   CMD(CALL PGM(PGM3B)) SCDTIME(210000) /* 21:00 */ 
ENDPGM                


メニュー処理

ここでは、メニュー処理のCLプログラムを紹介します。
CLプログラムの中で、以下のメニュー画面のファイルの入出力を行っています。

  MNU00                        業務開始メニュー            DD/DD/DD  TT:TT:TT  
                                                                               
      1. 受注関連処理                                                          
                                                                               
      2. 出庫関連処理                                                          
                                                                               
      3. 作業報告処理                                                          
                                                                               
      4. 仕入関連処理                                                          
                                                                               
      5. 入庫関連処理                                                          
                                                                               
      6. マスター保守                                                          
                                                                               
      7. 経理関連処理                                                          

                                                                               
      9. 保管・復旧処理                90. サイン・オフ                        
                                                                               
         処理選択 ==>  BB 
                       
   F3= 終了           

     メニュー番号誤り 

この画面では、1から9までの入力された番号に応じて、MNU01からMNU09までのプログラムを
呼出すことになっています。ただし、メニュー番号8番のときだけは、30番の標識で制御して、
「メニュー番号誤り」
のメッセージを表示します。メニュー番号が'1b'のかたちのときは、'b1'のようにプログラム内で右寄せします。
また'01'のかたちのときは、前の0をブランクに変えます。

この画面のDDSは次の通りです。

     A                                      DSPSIZ(24 80 *DS3)       
     A          R MNU00                                              
     A                                      TEXT(' 受発注処理 ')     
     A                                      CF03(03)                 
     A                                  1  2'MENU00'                 
     A                                  1 33' 業務開始メニュー '     
     A                                      DSPATR(RI)               
     A                                  1 60DATE                     
     A                                      EDTCDE(Y)                
     A                                  1 70TIME                     
     A                                  3  8'1. 受注処理 '           
     A                                  5  8'2. 出庫関連処理 '       
     A                                  7  8'3. 作業報告処理 '       
     A                                  9  8'4. 仕入発注処理 '       
     A                                 11  8'5. 入庫関連処理 '       
     A                                 13  8'6. マスター保守 '       
     A                                 15  8'7. 経理関連処理 '   
     A                                 18  8'9. 保管・復旧処理 ' 
     A                                 18 42'99. サインオフ '    
     A                                 23  2'F3= 終了 '          
     A                                 20 10' 処理選択 ==>'      
     A            MNNO           2A  B 20 24TEXT(' 選択番号 ')   
     A  30                             24  2' メニュー番号誤り '

メニュー処理のプログラムは次のとおりです。
PGM    
           DCLF       FILE(MNU00S)          /*  メニュー画面ファイル  */ 
           DCL        VAR(&C1) TYPE(*CHAR) LEN(1)                   
           CHGLIBL    LIBL(QTEMP WRKLIB QGPL)   /* ライブラリ・リスト変更 */
LOOP:      SNDRCVF    RCDFMT(MNU00R)           /*   画面入出力    */   
           CHGVAR     VAR(&IN30) VALUE('0')                         
/* F3  */                                                          
           IF         COND(&IN03 = '1') THEN(GOTO CMDLBL(END))      
/* SIGNOFF */                                                         
           IF         COND(&MNNO = '90') THEN(SIGNOFF)              
/*  右詰  */                                                          
           CHGVAR     VAR(&C1) VALUE(%SST(&MNNO 2 1))               
           IF         COND(&C1 = ' ')  +                            
                      THEN(CHGVAR VAR(&MNNO)  VALUE(' ' || &MNNO))  
           CHGVAR     VAR(&C1) VALUE(%SST(&MNNO 1 1))               
/* 前ゼロ消去 */
           IF         COND(&C1 = '0')  +                            
                      THEN(CHGVAR VAR(%SST(&MNNO 1 1)) VALUE(' '))  /* 擬似変数 */
                                                                      
           IF         COND(&MNNO = ' 1') THEN(CALL PGM(MNU01))      
           IF         COND(&MNNO = ' 2') THEN(CALL PGM(MNU02))      
           IF         COND(&MNNO = ' 3') THEN(CALL PGM(MNU03))    
           IF         COND(&MNNO = ' 4') THEN(CALL PGM(MNU04))    
           IF         COND(&MNNO = ' 5') THEN(CALL PGM(MNU05))    
           IF         COND(&MNNO = ' 6') THEN(CALL PGM(MNU06))    
           IF         COND(&MNNO = ' 7') THEN(CALL PGM(MNU07))    
           IF         COND(&MNNO = ' 8') THEN(CHGVAR VAR(&IN30) + 
                          VALUE('1'))      /* 標識をオンにする */ 
           IF         COND(&MNNO = ' 9') THEN(CALL PGM(MNU09))    
                                                                    
           GOTO LOOP    /*  LOOP  に戻ります。   */               
END:ENDPGM                                     





目次へ

(C)COPYRIGHT ISHIOKA KATSUHIDE 2000−2007