4

COBOLでテーブルの長さ(配列の要素数)を取得したいです。私が見た規則は、通常、作業用ストレージでの出現に一致するようにハードコードすることです。しかし、作業領域が変更されてプログラムが再コンパイルされた場合に、手続き部のステートメントを変更する必要がないように、コードで長さを取得したいと考えています。これは、メンテナンスの手間を減らし、5000 行のコードの使用を「見落とす」ことを防ぐためと、異なるテーブル長を持つ複数のプログラムで使用できるコピーコードにコードを含めることを可能にするためです。

だからここに私が思いついた唯一の解決策があります。

IDENTIFICATION DIVISION.
PROGRAM-ID. TESTPROG.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 THIS-LENGTH    PIC 9(04).
01 THIS-GROUP.
   05 THIS-TABLE  PIC X(20) OCCURS 15 TIMES.
PROCEDURE DIVISION.

    COMPUTE THIS-LENGTH = LENGTH OF THIS-GROUP
                         / LENGTH OF THIS-TABLE.
     DISPLAY LENGTH OF THIS-GROUP ' / ' LENGTH OF THIS-TABLE
             ' = ' THIS-LENGTH.
 EXIT-PROG.
     STOP RUN.

そして、これは出力します

000000300 / 000000020 = 0015

それは機能しますが、かなり不格好です。行の長さを取得するためだけに、行の周りにダミーのグループ レベルが必要です。これを行うより良い方法はありますか?

4

2 に答える 2

3

サイズに 78 のアイテムを使用し、それを OCCURS で使用します。次に、このサイズを外部で制御したい場合は、その周りにいくつかの条件文を追加できます...

バニラポータブルの例は次のようになります。

  WORKING-STORAGE SECTION.
  78 THIS-TABLE-SIZE VALUE 15.

   01 THIS-LENGTH    PIC 9(04).
   01 THIS-TABLE     PIC X(20) OCCURS THIS-TABLE-SIZE TIMES.
   PROCEDURE DIVISION.
      DISPLAY THIS-TABLE-SIZE.

ただし、$if.. を使用すると、次のようになります。

  WORKING-STORAGE SECTION.
  $if THIS-TABLE-SIZE defined
  $display THIS-TABLE-SIZE is changed
  $else
   78 THIS-TABLE-SIZE VALUE 15.
  $end

   01 THIS-LENGTH    PIC 9(04).
   01 THIS-TABLE     PIC X(20) OCCURS THIS-TABLE-SIZE TIMES.
   PROCEDURE DIVISION.
      DISPLAY THIS-TABLE-SIZE.

次に、デフォルトのコンパイル/実行により、次の結果が得られます。

Y:\DemoAndTests\size.of>cobol testprog.cbl nologo int();
* Generating testprog
* Data:         800     Code:         464     Literals:         144

Y:\DemoAndTests\size.of>run testprog
15

しかし、定数が設定されている場合...

Y:\DemoAndTests\size.of>cobol testprog.cbl nologo int() constant"THIS-TABLE-SIZE(20)";
THIS-TABLE-SIZE is changed
* Generating testprog
* Data:         896     Code:         464     Literals:         144

Y:\DemoAndTests\size.of>run testprog
20

また、78 レベルをコピーブックに移行することも検討します。

于 2013-01-17T15:18:59.347 に答える
1

それを「ダミーグループレベル」と表現するのは興味深いと思います。私は次のように定義します。

05  DELIBERATE-DUMMY-GROUP.
    10  FILLER OCCURS 15 TIMES.
        15  ACTUAL-ENTRY-NAME PIC X(20).

多くの場合、それに続くのは

05  SOMETHING-ELSE PIC something.

あなたが持っている場合

05  ACTUAL-ENTRY-NAME OCCURS 15 TIMES PIC X(20).
05  SOMETHING-ELSE PIC something.

あなたができる

定義

01  W-ADDRESS-OF-TABLE USAGE POINTER.
01  FILLER REDEFINES W-ADDRESS-OF-TABLE.
    05  W-AOT-AS-NUMBER COMP-5 PIC 9(9).
01  W-ADDRESS-OF-AFTER-TABLE USAGE POINTER.
01  FILLER REDEFINES W-ADDRESS-OF-AFTER-TABLE.
    05  W-AOAT-AS-NUMBER COMP-5 PIC 9(9).

SET W-ADDRESS-OF-TABLE TO ADDRESS OF ACTUAL-ENTRY-NAME ( 1 )
SET W-ADDRESS-OF-AFTER-TABLE TO ADDRESS OF SOMETHING-ELSE

SUBTRACT W-AOT-AS-NUMBER FROM W-AOAT-AS-NUMBER
  GIVING W-LENGTH-OF-TABLE
DIVIDE W-LENGTH-OF-TABLE BY LENGTH OF ACTUAL-ENTRY-NAME
  GIVING W-NO-OF-OCCURENCES

しかし、私は OCCURS をグループの一部として持つことを好みます。

注: 新しいフィールドを使用するようにコードを変更せずに「SOMETHING-ELSE」の前にフィールドを挿入すると、上記は機能しなくなります。また、フィールドに SYNC がある場合は、SYNC でも機能しません (実際には「必要」です)。

于 2013-01-16T12:46:21.393 に答える