【COBOL 読み1-15】デジャブと一粒の神〜数字チェックの法則

🧩今日の学び
・INSPECT…TALLYING でアルファベット混入を即検出できる仕組みを理解。
・係長いわく「BY と FOR ALL の違い」が今回の真のキモ。
・データ検証は“空欄 → 文字混入 → 数値チェック”の三段階で見る癖をつけよう。

今日のコード

           *> 数値チェック(英字混入をざっくり検出)
           MOVE ZERO TO CNT-ALPHA
           INSPECT F-QUANTITY-A   TALLYING CNT-ALPHA FOR ALL ALPHABETIC.
           INSPECT F-UNIT-PRICE-A TALLYING CNT-ALPHA FOR ALL ALPHABETIC.
           INSPECT F-TAX-RATE-A   TALLYING CNT-ALPHA FOR ALL ALPHABETIC.

           IF CNT-ALPHA > 0
              MOVE "NUMERIC PARSE ERROR" TO WS-MSG
              PERFORM WRITE-ERROR
              EXIT PARSE-AND-VALIDATE
           END-IF.

なるお)あれ、なんか見たことなうような。

これは・・・デジャヴですね!
視野が広いから見える力が強いんですよ俺!霊感強いんですよ!幽霊見たことないですけど!

見直しました?見直しましたよね!

デジャブの正体はINSPECTだった

係長)いや、デジャヴでも霊感でもねぇよ。前にちょろっと話した INSPECT … TALLYING がここで本番登場してるだけだ。

な)あれそっち?

           *> 必須チェック(空欄)
           MOVE ZERO TO CNT-BLANK
           IF F-ORDER-DATE-A = SPACES OR
              F-ORDER-ID-A   = SPACES OR
              F-QUANTITY-A   = SPACES OR
              F-UNIT-PRICE-A = SPACES OR
              F-TAX-RATE-A   = SPACES
              ADD 1 TO CNT-BLANK
           END-IF.

           IF CNT-BLANK > 0
              MOVE "MISSING REQUIRED FIELD" TO WS-MSG
              PERFORM WRITE-ERROR
              EXIT PARSE-AND-VALIDATE
           END-IF.

前回のこれかとおもったのは違ったです?

必須チェックと数値チェック:似て非なる二段構え

係)ああ、なるほどな。見た目が似てるからデジャヴ感じたんだろ。

前回のこれは 「必須チェック(空欄)」
「そもそも入ってなきゃダメな項目が空欄ならアウト」ってやつだな。

今回のは 「数値チェック」
 「一応値は入ってるけど、数字のはずの場所にアルファベットが混じってたらアウト」っていう次のステップだ。

な)え、つまり前回は「空じゃダメ」、今回は「変なアルファベットが混ざっててもダメ」ってことっすか?

係)そういうことだ。順番にフィルターかけて、空欄落として、次に文字混入落として、それでも残ったのだけが「まともなデータ」って扱いになる。

な)そうか!そうやって人類がフィルターにかけられていって、俺みたいな天才が残っていく感じですね!
納得です、深い深海のごとく納得なのです。

係)そうだな、ザルの網目に残った米粒と言えるな。

な)お米一粒に神様は宿りますもんね!神様に昇格ですね!INSPECT GODNESSですね!

係)どんだけ前向きなんだよ…

だから、そんなことはどうでもいいんだよ!

な)神に向かって!?

係)……

「このフィールドの中にアルファベットが混じってたら数えろ」っていう処理だ。

な)何の話ですか?

係)お前な!

な)神は殴られるのを拒否!

係)世が世ならお前の顔を変えられたのにな。

な)ひぃ!!

           *> 数値チェック(英字混入をざっくり検出)
           MOVE ZERO TO CNT-ALPHA
           INSPECT F-QUANTITY-A   TALLYING CNT-ALPHA FOR ALL ALPHABETIC.
           INSPECT F-UNIT-PRICE-A TALLYING CNT-ALPHA FOR ALL ALPHABETIC.
           INSPECT F-TAX-RATE-A   TALLYING CNT-ALPHA FOR ALL ALPHABETIC.

           IF CNT-ALPHA > 0
              MOVE "NUMERIC PARSE ERROR" TO WS-MSG
              PERFORM WRITE-ERROR
              EXIT PARSE-AND-VALIDATE
           END-IF.

係)「このフィールドの中にアルファベットが混じってたら数えろ」っていう処理だ。

な)さっきも言いませんでした?デジャブ!?

係)……お前聞く気あるのか?

な)ひっ!ありますよ!もちろんあります!
頭の天辺から地球のコアを超えて、ブラジルまで。

あ、実は日本の裏側ってブラジルじゃないって知ってまし……

いいえ、なんでもないです…
(凄まじい顔で睨まなくても…)

           MOVE ZERO TO CNT-ALPHA

係)さすがにこれはもういいだろ?

な)わかりますよ!
CNT-ALPHAに0を入れると。

係)そうだな

INSPECT F-QUANTITY-A TALLYING CNT-ALPHA FOR ALL ALPHABETIC.

そして、数量欄の文字列に「A」とか「B」とか入ってたら、そのぶん CNT-ALPHA に足される。

で、もし CNT-ALPHA > 0 だったら「数字のはずなのに文字が混じってるじゃねーか!」ってことで、エラー扱いして WRITE-ERROR に飛ばす。

な)ふむふむ

INSPECT F-QUANTITY-A TALLYING CNT-ALPHA FOR ALL ALPHABETIC.

TALLYINGは数えるって感じです?

係)それでいいぞ。

な)ALPHABETICって?

係)ALPHABETIC ってのは COBOLの条件名キーワードだ。

ALPHABETICを数える仕組み:TALLYINGの真価

ざっくり言うと「その文字が A~Z のアルファベットかどうか」って判定に使える。

INSPECT F-QUANTITY-A 
    TALLYING CNT-ALPHA FOR ALL ALPHABETIC

って書いたら、F-QUANTITY-A の中に A~Z が入ってたら、それを **「アルファベット文字」**としてカウントして CNT-ALPHA に足す。

な)じゃあ “123ABC” とか入ってたら、「A」「B」「C」で 3 が足されるってことっすね?

係)その通り。数字は数えないし、スペースや記号も ALPHABETIC には含まれない。純粋に A~Z だけだ。

な)あれ?ALLってBYじゃなかったでしたっけ?

係)お前、記憶力がスライド式黒板ぐらいしかないな。さっき上げたと思ったら、すぐ下に隠れてる。

           UNSTRING IN-REC DELIMITED BY ALL ","

まったくもう一回いくぞ。

「DELIMITED BY ALL ‘,’」の BY は「区切り文字を指定する」って文脈だったろ。

今回の FOR ALL ALPHABETIC は「この対象文字を片っ端から数えろ」って命令。

つまり、

  • BY …「何で切るか」
  • FOR ALL …「何を数えるか」

役割が違うんだよ。

な)はえー。

そしてその次のところはっと、

           IF CNT-ALPHA > 0
              MOVE "NUMERIC PARSE ERROR" TO WS-MSG
              PERFORM WRITE-ERROR
              EXIT PARSE-AND-VALIDATE
           END-IF.

CNT-ALPHAが1以上になってたら、ってことは、数字以外が混入してたら、、、

MOVE "NUMERIC PARSE ERROR" TO WS-MSG

NUMERIC PARSE ERRORをWS-MSGに入れ込んじゃって、WRITE-ERRORを実行だ!でも、PARSE-AND-VALIDATEから離脱となっているので、、、どっかに戻ると…

係)そうそう、その「どっか」が大事なんだよな。

いまコードの流れはこうだ。

  1. PROCESS-LOOP が「EOFになるまで繰り返すぞ」と構えてる。
  2. 1行読む → PARSE-AND-VALIDATE を PERFORM。
  3. もしエラーだったら MOVE “NUMERIC PARSE ERROR” TO WS-MSG して PERFORM WRITE-ERROR。
  4. そのあと EXIT PARSE-AND-VALIDATE で、その段落の残り処理をすっ飛ばして終了。
  5. 呼び出し元(PROCESS-LOOP)に戻る。

つまり、「エラー出した行はそこで処理終了、次の行を読み込め」っていう流れだ。

おむすび

な)はー、離脱って言っても、この世界線から離脱できないんですね。

あれ?じゃあ俺がEXITしても、結局また明日会社来るんすか?

現実から離脱できないじゃないですか!?

係)俺が退職願出しておくから、もう来なくていいぞ。

係長のワンポイント

INSPECT … TALLYING FOR ALL ALPHABETIC は「数字のはずの場所に A〜Z が混ざっていないか一気に数える」処理だ。
CNT-ALPHA は “何個混入したか” を示す指標で、1つでもあれば即アウト。
必須チェック → 数値チェックの順でフィルターを重ねるのが COBOLの定石。
EXIT PARSE-AND-VALIDATE は“段落を抜けて次の行へ進む”だけで関数脱出ではない。
つまり「変な文字が混じるだけで即切り捨て、次のレコードへ」が今回の流れだ。

― 目次(読みシリーズ)へ戻る ―

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする