構造化プログラミングの方法

1:構造化プログラミングの方法
江須扇 08/19 14:00
こんにちは、ご無沙汰しております。江須扇です。

今日は初歩的な事をご教授していただきたく投稿しました。
過去のCOBOLのプログラムはGO TO だらけなのでメンテナンスは、
そのままGO TO だらけで修正しております。
構造化プログラミングはいままでしていないので、いまさらと思っておりまし
たが、新規プログラムをGOTOレスで作ろうと思ったのですが中々巧くいき
ません。サンプルを作ったのですが、おかしいところを添削していただけない
でしょうか?

項目Aと項目Bを入力しその表示をして項目Bに戻るというものです。
また、項目BでBTABをすれば項目Aに戻る必要もあります。
項目A又は項目BでPF9を入力すると終了とします。
実際はMAIN−RTNはもっと複雑になります。

コーディング例

----------------------------------------------------------------------

000010 IDENTIFICATION   DIVISION.
000020 PROGRAM-ID.      ACPTST.
000030 ENVIRONMENT      DIVISION.
000040 CONFIGURATION    SECTION.
000050 SOURCE-COMPUTER. EXPRESS5800.
000060 OBJECT-COMPUTER. EXPRESS5800.
000070 DATA             DIVISION.
000080 WORKING-STORAGE  SECTION.
000090 77  A-CELL       PIC  X(05).
000100 77  B-CELL       PIC  X(05).
000110 01  SWITCH-FLAG  PIC  9(01) VALUE 0.
000120 88  SWITCH-HTAB             VALUE 1.
000130 88  SWITCH-BSKIP            VALUE 9.
000140 SCREEN  SECTION.
000150 SD  GAMEN END    STATUS IS  END-STATUS.
000160 01  ACEP-A CLEAR SCREEN.
000170     02 LINE 05   COLUMN 10 PIC X(05) USING A-CELL.
000180 01  ACEP-B.
000190     02 LINE 10   COLUMN 10 PIC X(05) INTO  B-CELL.
000200 01  DISP-C.
000210     02 LINE 15   COLUMN 10 PIC N(05) FROM  A-CELL.
000220     02 LINE 20   COLUMN 10 PIC N(05) FROM  B-CELL WAIT.
000230 PROCEDURE        DIVISION.
000240 INIT-RTN.
000250     SET SWITCH-BSKIP TO TRUE.
000260     PERFORM UNTIL END-STATUS = "P9"
000270       EVALUATE TRUE
000280           WHEN SWITCH-BSKIP
000290                ACCEPT    ACEP-A
000300                IF END-STATUS = "01"
000310                                     SET SWITCH-HTAB TO TRUE
000320                END-IF
000330           WHEN SWITCH-HTAB
000340                DISPLAY   ACEP-A
000350                ACCEPT    ACEP-B
000360                EVALUATE  END-STATUS
000370                    WHEN  "01"       PERFORM MAIN-RTN
000380                    WHEN  "09"       SET SWITCH-BSKIP TO TRUE
000390                END-EVALUATE
000400       END-EVALUATE
000410     END-PERFORM.
000420     STOP RUN.
000430******************************************************************
000440 MAIN-RTN.
000450     DISPLAY DISP-C.


2:(再投稿)構造化プログラミングの方法
江須扇 08/19 14:18

コーディング例


----------------------------------------------------------------------

000010 IDENTIFICATION DIVISION.
000020 PROGRAM-ID. ACPTST.
000030 ENVIRONMENT DIVISION.
000040 CONFIGURATION SECTION.
000050 SOURCE-COMPUTER. EXPRESS5800.
000060 OBJECT-COMPUTER. EXPRESS5800.
000070 DATA DIVISION.
000080 WORKING-STORAGE SECTION.
000090 77 A-CELL PIC X(05).
000100 77 B-CELL PIC X(05).
000110 01 SWITCH-FLAG PIC 9(01) VALUE 0.
000120 88 SWITCH-HTAB VALUE 1.
000130 88 SWITCH-BSKIP VALUE 9.
000140 SCREEN SECTION.
000150 SD GAMEN END STATUS IS END-STATUS.
000160 01 ACEP-A CLEAR SCREEN.
000170     02 LINE 05 COLUMN 10 PIC X(05) USING A-CELL.
000180 01 ACEP-B.
000190     02 LINE 10 COLUMN 10 PIC X(05) INTO B-CELL.
000200 01 DISP-C.
000210     02 LINE 15 COLUMN 10 PIC N(05) FROM A-CELL.
000220     02 LINE 20 COLUMN 10 PIC N(05) FROM B-CELL WAIT.
000230 PROCEDURE DIVISION.
000240 INIT-RTN.
000250     SET SWITCH-BSKIP TO TRUE.
000260     PERFORM UNTIL END-STATUS = "P9"
000270       EVALUATE TRUE
000280           WHEN SWITCH-BSKIP
000290                ACCEPT ACEP-A
000300                IF END-STATUS = "01"
000310                                     SET SWITCH-HTAB TO TRUE
000320                END-IF
000330           WHEN SWITCH-HTAB
000340                DISPLAY ACEP-A
000350                ACCEPT ACEP-B
000360                EVALUATE END-STATUS
000370                    WHEN "01" PERFORM MAIN-RTN
000380                    WHEN "09" SET SWITCH-BSKIP TO TRUE
000390                END-EVALUATE
000400       END-EVALUATE
000410     END-PERFORM.
000420     STOP RUN.
000430******************************************************************
000440 MAIN-RTN.
000450     DISPLAY DISP-C.


3:Re:(再投稿)構造化プログラミングの方法
EXCHANGE 08/20 03:40
☆ バッチ処理プログラムでは、専ら「構造化」で書くのですが、入力系(会話型)では、GOTOをつかっていますので、あまりいい考えは浮かばないのですが。。

例えば、次のような考え方はダメでしょうか。。

 MOVE 1  TO CUR-POSITION
  MOVE 2  TO CUR-POSITION-MAX
  MOVE SPACE  TO END-STATUS
*
  PERFORM  UNTIL END-STATUS = "P9"
              OR CUR-POSITON > CUR-POSITION-MAX
    EVALUATE  CUR-POSITION
      WHEN 0
      WHEN 1
             ACCEPT   ACEP-A-ACP
             EVALUATE END-STATUS 
               WHEN "09"
                    SUBTRACT 1  FROM CUR-POSITION
               WHEN OTHER
                    DISPLAY ACEP-A-DSP
                    ADD 1       TO   CUR-POSITON
             END-EVALUATE
      WHEN 2
             ACCEPT  ACEP-B-ACP 
             EVALUATE END-STATUS 
               WHEN "09"
                    SUBTRACT 1  FROM CUR-POSITION
               WHEN OTHER
                    DISPLAY ACEP-B-DSP
                    ADD 1       TO   CUR-POSITON
             END-EVALUATE
      WHEN OTHER
             CONTINUE
    END-EVALUATE
  END-PERFORM.



5:Re:(再投稿)構造化プログラミングの方法
EXCHANGE 08/20 11:39
WHEN 0 の時の取り扱いがまずいので、訂正です。
まだまだヘンかも。。。
適当に直して下さい。


*
PERFORM UNTIL END-STATUS = "P9"
           OR FOCUS-POSITON > FOCUS-POSITION-MAX
*
  EVALUATE FOCUS-POSITION
    WHEN 1
          ACCEPT ACEP-A-ACP
          EVALUATE END-STATUS
            WHEN "09"
                SUBTRACT 1 FROM FOCUS-POSITION
            WHEN OTHER
                DISPLAY ACEP-A-DSP
                ADD 1 TO FOCUS-POSITON
          END-EVALUATE
    WHEN 2
          ACCEPT ACEP-B-ACP
          EVALUATE END-STATUS
            WHEN "09"
                SUBTRACT 1 FROM FOCUS-POSITION
            WHEN OTHER
                DISPLAY ACEP-B-DSP
                ADD 1 TO FOCUS-POSITON
          END-EVALUATE
    WHEN OTHER
          CONTINUE
  END-EVALUATE
*
  IF FOCUS-POSITION = 0
    THEN MOVE 1 TO FOCUS-POSITION
  END-IF
*
END-PERFORM.


6:もう少しだけ直しました。
EXCHANGE 08/20 13:09
もう少しだけ直しました。
 いかがでしょうか?


MOVE 1 TO FOCUS-POSITION.
MOVE 2 TO FOCUS-POSITION-MAX.
MOVE SPACE TO END-STATUS.
MOVE SPACE TO WINDOW-STATUS.
*
PERFORM UNTIL END-STATUS = "P9"
             OR WINDOW-STATUS = "EXIT"
*
  EVALUATE FOCUS-POSITION
    WHEN 1
          ACCEPT ACEP-A-ACP
          EVALUATE END-STATUS
            WHEN "09"
                SUBTRACT 1 FROM FOCUS-POSITION
            WHEN OTHER
                DISPLAY ACEP-A-DSP
                PERFORM ACEP-A-CHECK-SUB
                IF ERR-FLAG = 1
                  THEN
                      DISPLAY ERROR-MSG-A
                  ELSE
                      ADD 1 TO FOCUS-POSITON
                END-IF
          END-EVALUATE
    WHEN 2
          ACCEPT ACEP-B-ACP
          EVALUATE END-STATUS
            WHEN "09"
                SUBTRACT 1 FROM FOCUS-POSITION
            WHEN OTHER
                DISPLAY ACEP-B-DSP
                PERFORM ACEP-B-CHECK-SUB
                IF ERR-FLAG = 1
                  THEN
                      DISPLAY ERROR-MSG-B
                  ELSE
                      ADD 1 TO FOCUS-POSITON
                END-IF
          END-EVALUATE
    WHEN OTHER
          CONTINUE
  END-EVALUATE
*
  IF FOCUS-POSITION = 0
    THEN MOVE 1 TO FOCUS-POSITION
  END-IF
*
  IF FOCUS-POSITION > FOCUS-POSITION-MAX
    THEN MOVE "EXIT" TO WINDOW-STATUS
  END-IF
*
END-PERFORM.


7:Re:もう少しだけ直しました(その2)
EXCHANGE 08/21 12:20
もう少しだけ直しました。(その2)
 いかがでしょうか??


*
MOVE 1 TO FOCUS-POSITION.
MOVE 2 TO FOCUS-POSITION-MAX.
MOVE SPACE TO END-STATUS.
MOVE SPACE TO WINDOW-STATUS.
*
PERFORM UNTIL END-STATUS = "P9"
             OR WINDOW-STATUS = "EXIT"
*
  EVALUATE FOCUS-POSITION
    WHEN 1
          ACCEPT ACEP-A-ACP
          EVALUATE END-STATUS
            WHEN "09"
                SUBTRACT 1 FROM FOCUS-POSITION
            WHEN "01"
                DISPLAY ACEP-A-DSP
                PERFORM ACEP-A-CHECK-SUB
                IF ERR-FLAG = 1
                  THEN
                      DISPLAY ERROR-MSG-A
                  ELSE
                      ADD 1 TO FOCUS-POSITON
                END-IF
            WHEN OTHER
                CONTINUE
          END-EVALUATE
    WHEN 2
          ACCEPT ACEP-B-ACP
          EVALUATE END-STATUS
            WHEN "09"
                SUBTRACT 1 FROM FOCUS-POSITION
            WHEN "01"
                DISPLAY ACEP-B-DSP
                PERFORM ACEP-B-CHECK-SUB
                IF ERR-FLAG = 1
                  THEN
                      DISPLAY ERROR-MSG-B
                  ELSE
                      ADD 1 TO FOCUS-POSITON
                END-IF
            WHEN OTHER
                CONTINUE
          END-EVALUATE
    WHEN OTHER
          CONTINUE
  END-EVALUATE
*
  IF FOCUS-POSITION = 0
    THEN MOVE 1 TO FOCUS-POSITION
  END-IF
*
  IF FOCUS-POSITION > FOCUS-POSITION-MAX
    THEN MOVE "EXIT" TO WINDOW-STATUS
  END-IF
*
END-PERFORM.



8:Re:もう少しだけ直しました(その2)
江須扇 08/22 12:53
EXCHAGEさん早速いろいろと回答を頂きありがとうございます。
いろいろと考えていただきありがとうございます。

結論としてはやはり自分で何らかのスイッチを定義する必要があると言う事ですか。
A−VXのCOBOLの機能で使えるものは無いということですね。

もう一度、やりたい事を説明しますと


項目A入力
↓__↑(BTABを押すと項目Aに戻る)
項目B入力
↓__↑(項目Bに戻る、入力すると結果表示に行く)
結果表示

という処理です。

EXCHAGEさんの例では結果表示はもう一ランク上で括れということですね。


*
MOVE 1 TO FOCUS-POSITION.
MOVE 2 TO FOCUS-POSITION-MAX.
MOVE SPACE TO END-STATUS.
MOVE SPACE TO WINDOW-STATUS.
*
PERFORM UNTIL END-STATUS = "P9"        ←私か追加した部分
             OR WINDOW-STATUS = "EXIT"     ←私か追加した部分
  PERFORM UNTIL END-STATUS = "P9"
             OR WINDOW-STATUS = "EXIT"
*
〜中略〜
(EXCHANGEさんの内容)
*
  END-PERFORM 
結果表示処理                ←私か追加した部分
MOVE 2 TO FOCUS-POSITION.          ←私か追加した部分
END-PERFORM.                 ←私か追加した部分
STOP RUN.                  ←私か追加した部分



9:Re:もう少しだけ直しました(その2)
EXCHANGE 08/22 13:50
☆ 「雛形」ではカーソルの位置の制御を、FOCUS-POSITIONで

  行っていますので、

  例えば項目Bの入力後、項目Bの再入力へLOOPさせたい場合は、 FOCUS-POSITIONを変更せずに進めるとうまくいくのでは

  ないかと思います。(間違ってたらごめんなさい)



  項目入力時に(HTAB)(BSKIP)以外のキーを押下した場合も(F9)をのぞいて同じ項目の再入力に戻ります。

 

☆ なおA−VXの場合、SKIPキーの扱いが問題かとも思います。

 経験された方はご存じと思うのですが、数字項目の表示位置が初期状態では「空白」(=文字)となるので「0」等を編集表示(例:ZZZZ−)しておかないと、いきなりSKIPを押下−−>「NON−NUMERIC」エラーになります。入力後、カンマ付編集をしている場合も(カンマが文字と見なされるので)要注意です。この辺をうまく織り込もうとすると「雛形」を使っても結構、面倒な気がします。





*
MOVE 1 TO FOCUS-POSITION.
MOVE 2 TO FOCUS-POSITION-MAX.
MOVE SPACE TO END-STATUS.
MOVE SPACE TO WINDOW-STATUS.
*
PERFORM UNTIL END-STATUS = "P9"
             OR WINDOW-STATUS = "EXIT"
*
  EVALUATE FOCUS-POSITION
    WHEN 1
          ACCEPT ACEP-A-ACP
          EVALUATE END-STATUS
            WHEN "09"
                SUBTRACT 1 FROM FOCUS-POSITION
            WHEN "01"
                DISPLAY ACEP-A-DSP
                PERFORM ACEP-A-CHECK-SUB
                IF ERR-FLAG = 1
                  THEN
                      DISPLAY ERROR-MSG-A
                  ELSE
                      ADD 1 TO FOCUS-POSITON
                END-IF
            WHEN OTHER
                CONTINUE
          END-EVALUATE
    WHEN 2
          ACCEPT ACEP-B-ACP
          EVALUATE END-STATUS
            WHEN "09"
                SUBTRACT 1 FROM FOCUS-POSITION
            WHEN "01"
                DISPLAY ACEP-B-DSP
                PERFORM ACEP-B-CHECK-SUB
                IF ERR-FLAG = 1
                  THEN
                      DISPLAY ERROR-MSG-B
                  ELSE
                      (処理結果表示)
                      (FOCUS-POSITONを1UPしない)
                END-IF
            WHEN OTHER
                CONTINUE
          END-EVALUATE
    WHEN OTHER
          CONTINUE
  END-EVALUATE
*
  IF FOCUS-POSITION = 0
    THEN MOVE 1 TO FOCUS-POSITION
  END-IF
*
  IF FOCUS-POSITION > FOCUS-POSITION-MAX
    THEN MOVE "EXIT" TO WINDOW-STATUS
  END-IF
*
END-PERFORM.



10:Re:もう少しだけ直しました(その2)
江須扇 08/24 15:34
EXCHANGEさん、いろいろとありがとうございます。

流れの基本は私と同じと思いましたが大きく違うところが解りました。
私はどうしてもメモリの少ない時の癖でプログラムの解りやすさより、ステップ数重視で1ステップでも少なくなる事を考えてしまいます。
保守性を考えたらわかり易さ重視の方が良いようですね。
多分、私の元のコーディングは
WHEN SWITCH−BTABで1項目の入力
WHEN SWITCH−HTABで2項目の入力
になっており意味不明という事ですね。
そうですステップ数削減で意味不明です。
3項目を作ったどうするか考えておりませんでした。
それにしてもCOBOL側でもっとステップ数のすくなくなる
命令がないのでしょうかね?

1-

BluesBB ©Sting_Band