COBOL入門 Mission2-4 値の取得方法

処 理 内 容 PROGRAM-ID 難易度 言語
カウントする値を指定する CNT004 1 COBOL
1:処理図
2:処理概要

[CNT002に条件追加]
カウントする値を(1〜9999の範囲で)指定出来るようにする

表示は100飛びで行なう(100 200 300 〜)
3:その他

★値の取得命令 [ ACCEPT ]

    ACCEPT  任意の項目名

ええと、まず今回の問題ではタイプイン命令(ACCEPT)が出題されてます。COBOLでは処理中に手動で値を入力するには、このACCEPT命令で行なうか、JCL(後に説明します)で受け渡す方法が一般的です。表示は100ずつということなので注意して組んでみましょう。

 IDENTIFICATION             DIVISION.
 PROGRAM-ID.                CNT004.
 DATA                       DIVISION.
 WORKING-STORAGE            SECTION.
 01  WCNT                   PIC 9(04) VALUE 0.
* ↑この項目をタイプインで受け取り比較する
 01  CNT                    PIC 9(04) VALUE 0.
 01  CNT1                   PIC 9(03) VALUE 0.
 01  WTIME.
     03  HH                 PIC 9(02).
     03  MM                 PIC 9(02).
     03  SS                 PIC 9(02).
 01  STIME                  PIC 9(06) VALUE 0.
 01  ETIME                  PIC 9(06) VALUE 0.
 01  XTIME                  PIC 9(06) VALUE 0.
 PROCEDURE                  DIVISION.
    DISPLAY "!!! CNT 9(04) TYPE-IN !!!"
*   ↑DISPLAY命令を直前に行なえば、タイプイン時に
*     指定した文字列を画面に表示できます
    ACCEPT   WCNT
    ACCEPT   WTIME  FROM  TIME
    COMPUTE  STIME  =  (HH * 3600) + (MM * 60) + SS
    PERFORM  UNTIL  CNT  =  WCNT
*  ↑先ほど指定したWCNTを超えるまで繰り返す
        ADD  1  TO  CNT  CNT1
        IF   CNT1   =  100
             THEN   DISPLAY  CNT
                    MOVE  ZERO  TO  CNT1
             ELSE   CONTINUE
        END-IF
    END-PERFORM
    ACCEPT   WTIME  FROM  TIME
    COMPUTE  ETIME  =  ((HH * 3600) + (MM * 60) + SS)
    COMPUTE  XTIME  =  ETIME - STIME
    COMPUTE  HH     =  XTIME / 3600
    COMPUTE  XTIME  =  XTIME - (HH * 3600)
    COMPUTE  MM     =  XTIME / 60
    COMPUTE  SS     =  XTIME - (MM * 60)
    DISPLAY  "TIME  =  " HH ":" MM ":" SS
    DISPLAY  "<<<  CNT004  ENDED  >>>"
    STOP  RUN.

ACCEPT命令だけでもちゃんと動作はします。ただそうなると、画面には入力を受け入れる状態にはなりますが、特に何も表示されないため何の入力をするのかよくわかりません。そこでACCEPT命令の直前にDISPLAY命令を入れてあげるようにしましょう。こうすれば画面には「!!! CNT 9(04) TYPE-IN !!!」の文字に続いて「?」が表示されるようになります。

後はそれほど難しい箇所はありませんね。ACCEPT命令で入力したWCNTに達するまでCNT+1を繰り返せばOK。


☆こんなこともやってみよう!

カウント値を繰返し指定出来るようにする。ただし9999が入力されたらプログラムを終了する。

先ほどのプログラムは、1回ACCEPTでタイプイン(入力)したらお終いでした。これじゃあ面白くない。だったら自分で改造してみましょう。

[ヒント] 繰返し処理する場合はその都度カウンタをゼロに戻すことが必要!

以下の説明文内に模範解答を掲載しています。

※前画面に戻る場合は、[Back space]キーが便利です  ▼メニューにジャンプ

手続き名(段落)とGO TO命令

プログラムを書いていると、ある一連の作業を何度も繰り返す場面があります。その都度同じ処理を書いても勿論間違いではありませんが、処理をひとつの塊(ブロック)として定義することで、解かり易くバグの少ないスマートなコードを書くことができます。

*タイプインを繰り返し指定できるように改造(9999は終了)
 IDENTIFICATION             DIVISION.
 PROGRAM-ID.                CNT041.
 ENVIRONMENT                DIVISION.
 CONFIGURATION              SECTION.
 DATA                       DIVISION.
 WORKING-STORAGE            SECTION.
 01  WCNT                   PIC 9(04) VALUE 0.
 01  CNT                    PIC 9(04) VALUE 0.
 01  CNT1                   PIC 9(03) VALUE 0.
 01  WTIME.
     03  HH                 PIC 9(02).
     03  MM                 PIC 9(02).
     03  SS                 PIC 9(02).
 01  STIME                  PIC 9(06) VALUE 0.
 01  ETIME                  PIC 9(06) VALUE 0.
 PROCEDURE                  DIVISION.
 A.    *>8カラム目から始まり、ピリオドで終わるものを「段落」と呼びます
     DISPLAY "!!! CNT 9(04) TYPE-IN END・・・9999!!!"
     ACCEPT   WCNT
     IF  WCNT  =  9999
         THEN
            DISPLAY "<<< CNT041 - ENDED >>>"
            STOP  RUN
         ELSE
            MOVE  ZERO  TO  CNT  CNT1
            ACCEPT   WTIME  FROM  TIME
            COMPUTE  STIME  =  (HH * 3600) + (MM * 60) + SS
            PERFORM  UNTIL  CNT  =  WCNT
               ADD  1  TO  CNT  CNT1
               IF  CNT1   =  100
                   THEN   DISPLAY  CNT
                          MOVE  ZERO  TO  CNT1
                   ELSE   CONTINUE
               END-IF
            END-PERFORM
            ACCEPT   WTIME  FROM  TIME
            COMPUTE  ETIME  =
                     ((HH * 3600) + (MM * 60) + SS) - STIME
            COMPUTE  HH     =  ETIME / 3600
            COMPUTE  ETIME  =  ETIME - (HH * 3600)
            COMPUTE  MM     =  ETIME / 60
            COMPUTE  SS     =  ETIME - (MM * 60)
            DISPLAY  "TIME  =  " HH ":" MM ":" SS
     END-IF
     GO  TO  A.   *>「A」段落に戻り、繰返し処理を可能にしている

赤色で表示されている部分「A.」ここが今回のプログラムのキモになります。COBOLプログラムでは、必ず処理は行の上から下へ、命令語が1行内に複数あれば左から右へ処理をおこないます。つまり一旦下まで処理されたプログラムを再度上位に戻すためには、何かしら目印を立ててあげる必要があるのです。この目印を手続き名(段落)と呼びます。こう断言して書いてしまうと語弊がありますが、通常は何かしら一連の処理単位で繰り返す場合に利用されています。

手続き名
一連の命令群に付けた名前(或る機能を表す)


※前画面に戻る場合は、[Back space]キーが便利です  ▼メニューにジャンプ

整構造化のススメ

先ほどのプログラムでも問題なく動作はします。しますけど、GOTO命令というのは、行きっぱなしになる命令です。簡単なプログラムであれば問題ないのですが、複雑な処理になればなるほどGOTO命令でプログラムが余計複雑になる場合があります。そこで、同じ処理をよりスマートに組んでみましょう。

* 整構造化sample
 IDENTIFICATION             DIVISION.
 PROGRAM-ID.                CNT0042.
 DATA                       DIVISION.
 WORKING-STORAGE            SECTION.
 01  WCNT                   PIC 9(04) VALUE 0.
 01  CNT                    PIC 9(04) VALUE 0.
 01  CNT1                   PIC 9(03) VALUE 0.
 01  WTIME.
     03  HH                 PIC 9(02).
     03  MM                 PIC 9(02).
     03  SS                 PIC 9(02).
 01  STIME                  PIC 9(06) VALUE 0.
 01  ETIME                  PIC 9(06) VALUE 0.
 PROCEDURE                  DIVISION.
 *    ***** WCNT = 9999 まで繰返し *****
      PERFORM  UNTIL  WCNT = 9999
        DISPLAY "!!! CNT 9(04) TYPE-IN END・・・9999"
 *    ***** WCNT の取得 *****
        ACCEPT  WCNT
        IF  WCNT  =  9999
            THEN
               CONTINUE
            ELSE
*              ***** スタートタイム の取得 *****
               MOVE  ZERO  TO  CNT  CNT1
               ACCEPT  WTIME  FROM  TIME
               COMPUTE STIME = (HH * 3600) + (MM * 60) + SS
*              ***** カウント の取得 *****
               PERFORM  UNTIL  CNT  =  WCNT
                   ADD  1  TO  CNT  CNT1
                   IF  CNT1  =  100
                       THEN
                          DISPLAY  CNT
                          MOVE  ZERO  TO  CNT1
                       ELSE
                          CONTINUE
                   END-IF
               END-PERFORM
*              ***** エンドタイム の取得 *****
               ACCEPT  WTIME FROM  TIME
*              ***** 所要時分の算出・表示 *****
               COMPUTE ETIME = ((HH * 3600) + (MM * 60) + SS)
                                                      - STIME
               COMPUTE HH    = ETIME / 3600
               COMPUTE ETIME = ETIME - (HH * 3600)
               COMPUTE MM    = ETIME / 60
               COMPUTE SS    = ETIME - (MM * 60)
               DISPLAY "TIME  = " HH ":" MM ":" SS
        END-IF
      END-PERFORM
      STOP RUN.

これが整構造と言われる手法で書かれたサンプルです。手続き名を利用しないで、「PERFORM UNTIL」にて処理の繰り返しをおこなっているのがわかりますか?

整構造

総てのプログラムは1つの入り口・1つの出口を持つSequence,Do-Until,Do-While,If-Then-Else,Caseの5つの機能の組合せで実現可能である(ダイクストラの構造化定理より)

ここら辺のことは、私よりも大先輩のVOKさんのサイト、 何で今更構造化プログラム の中で詳しく述べられているので、まずはそちらを読んでみて下さい。要約してしまえば、シンプルでより独立性の高いプログラムを1つずつ組み上げたプログラムは、絶対バグが出るはずはありません。つまりテストすらしなくていいということになります。そんなバカな…そう思う人もいるでしょうが、完全なる整構造が成されたプログラムではバグは理論上ゼロになります。興味を持たれた方は、ぜひ遊びに行ってみて下さい。

※前画面に戻る場合は、[Back space]キーが便利です  ▼メニューにジャンプ

<< Back    Index    Next >>   < Top >