Klausa OCCURS menyediakan elemen data yang berulang, sehingga satu definisi dapat menampung banyak nilai dengan tata letak yang seragam di memori. Topik ini membahas tabel ukuran tetap berdimensi satu, tabel yang dibentuk dari grup item, dan tabel berdimensi dua, beserta cara menghitung ukuran memorinya. Demo utamanya berupa program yang mengisi tabel dengan lima nilai, menelusurinya dengan PERFORM VARYING, lalu menjumlahkan isinya.
Mengulang item dengan OCCURS#
OCCURS n TIMES mengulang definisi sebuah item data sebanyak n kali, dan struktur
hasilnya disebut tabel (table), yaitu padanan konsep array pada bahasa
pemrograman lain. Deklarasi 05 NILAI-HARI PIC 9(3) OCCURS 5 TIMES menyediakan
lima field numerik tiga digit yang berdampingan di memori, sehingga grup
NILAI-HARIAN yang membungkusnya berukuran 15 byte. Setiap elemen diakses melalui
subskrip (subscript) yang ditulis dalam tanda kurung setelah nama item.
Penomorannya berbasis satu, artinya elemen pertama adalah NILAI-HARI(1) dan
bukan NILAI-HARI(0). Konvensi ini berbeda dari banyak bahasa modern yang
memulai penomoran dari nol.
Subskrip boleh berupa literal maupun variabel, sehingga satu pernyataan seperti
ADD NILAI-HARI(I) TO TOTAL-NILAI cukup ditulis sekali di dalam badan perulangan.
PERFORM VARYING menjadi pasangan alami OCCURS karena variabel pengendalinya
berjalan dari 1 sampai jumlah pengulangan. Program berikut
mengisi lima nilai penjualan harian ke dalam tabel, menampilkannya satu per
satu, lalu menjumlahkan seluruhnya.
IDENTIFICATION DIVISION.
PROGRAM-ID. OCCURS-DASAR.
*--------------------------------------------------------------
* Tabel berdimensi satu: pengisian, penelusuran, penjumlahan.
*--------------------------------------------------------------
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NILAI-HARIAN.
05 NILAI-HARI PIC 9(3) OCCURS 5 TIMES.
01 TOTAL-NILAI PIC 9(5) VALUE 0.
01 I PIC 9(2).
PROCEDURE DIVISION.
UTAMA.
MOVE 80 TO NILAI-HARI(1)
MOVE 75 TO NILAI-HARI(2)
MOVE 90 TO NILAI-HARI(3)
MOVE 85 TO NILAI-HARI(4)
MOVE 70 TO NILAI-HARI(5)
PERFORM TAMPIL-SATU
VARYING I FROM 1 BY 1 UNTIL I > 5
PERFORM JUMLAHKAN-SATU
VARYING I FROM 1 BY 1 UNTIL I > 5
DISPLAY "Total lima hari : " TOTAL-NILAI
STOP RUN.
TAMPIL-SATU.
DISPLAY "Hari ke-" I " : " NILAI-HARI(I).
JUMLAHKAN-SATU.
ADD NILAI-HARI(I) TO TOTAL-NILAI.Hari ke-01 : 080
Hari ke-02 : 075
Hari ke-03 : 090
Hari ke-04 : 085
Hari ke-05 : 070
Total lima hari : 00400Angka seperti 080 dan 00400 memuat nol di depan karena picture 9(3) dan
9(5) menyimpan digit dengan lebar tetap. Perulangan
PERFORM TAMPIL-SATU VARYING I FROM 1 BY 1 UNTIL I > 5 menaikkan I dari 1
sampai 5, dan pada setiap iterasi subskrip NILAI-HARI(I) menunjuk elemen yang
berbeda. Perulangan kedua menjumlahkan isi tabel dengan pola yang sama, sehingga
angka 00400 pada baris terakhir merupakan hasil penjumlahan 80, 75, 90, 85, dan
70.
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./occurs.
# kompilasi program tabel berdimensi satu
cobc -x occurs.cblTabel dari grup item#
Elemen tabel paling sering berupa grup, yaitu satu item level 05 yang diberi
OCCURS dan memuat beberapa item anak sekaligus. Pola ini memodelkan daftar record
secara alami, misalnya daftar nilai kelas yang setiap barisnya memuat nama dan
nilai satu siswa. Ukuran tabelnya dihitung dengan mengalikan jumlah pengulangan
dengan ukuran satu elemen. REKAMAN-KELAS pada program berikut berukuran
33 byte karena terdiri atas tiga pengulangan yang masing-masing berukuran 11 byte.
IDENTIFICATION DIVISION.
PROGRAM-ID. TABEL-GRUP.
*--------------------------------------------------------------
* Tabel dari grup: setiap elemen memuat beberapa field.
*--------------------------------------------------------------
DATA DIVISION.
WORKING-STORAGE SECTION.
01 REKAMAN-KELAS.
05 DATA-SISWA OCCURS 3 TIMES.
10 NAMA-SISWA PIC X(8).
10 NILAI-SISWA PIC 9(3).
01 I PIC 9(2).
PROCEDURE DIVISION.
UTAMA.
MOVE "Ali" TO NAMA-SISWA(1)
MOVE 85 TO NILAI-SISWA(1)
MOVE "Budi" TO NAMA-SISWA(2)
MOVE 78 TO NILAI-SISWA(2)
MOVE "Citra" TO NAMA-SISWA(3)
MOVE 92 TO NILAI-SISWA(3)
PERFORM TAMPIL-SATU
VARYING I FROM 1 BY 1 UNTIL I > 3
DISPLAY "[" REKAMAN-KELAS "]"
STOP RUN.
TAMPIL-SATU.
DISPLAY NAMA-SISWA(I) "|" NILAI-SISWA(I).Ali |085
Budi |078
Citra |092
[Ali 085Budi 078Citra 092]Tiga baris pertama menampilkan satu elemen tabel per baris, dengan subskrip I
yang sama dipakai untuk kedua field anaknya, yaitu NAMA-SISWA(I) dan
NILAI-SISWA(I). Baris keempat menampilkan isi grup REKAMAN-KELAS sebagai satu
rangkaian byte. Isinya berupa gabungan ketiga entri tanpa pemisah, lengkap
dengan spasi pengisi picture X(8), karena tabel dari grup tidak lebih dari
rangkaian byte yang berulang secara teratur.
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan
./tabel-grup.
# kompilasi program tabel dari grup
cobc -x tabel-grup.cblDimensi dua dengan OCCURS bersarang#
Tabel berdimensi dua dibentuk dengan menempatkan OCCURS di dalam item yang juga
ber-OCCURS. Deklarasi BARIS-GRID OCCURS 3 TIMES yang memuat
NILAI-SEL PIC 9(2) OCCURS 4 TIMES menghasilkan dua belas elemen berukuran 24
byte. Aksesnya memakai dua subskrip dalam satu tanda kurung, misalnya
NILAI-SEL(2, 3). Subskrip pertama memilih pengulangan BARIS-GRID,
sedangkan subskrip kedua memilih pengulangan NILAI-SEL. Koma pemisah boleh
diganti spasi, sehingga NILAI-SEL(2 3) bermakna sama.
IDENTIFICATION DIVISION.
PROGRAM-ID. DIMENSI-DUA.
*--------------------------------------------------------------
* Tabel berdimensi dua: OCCURS di dalam OCCURS.
*--------------------------------------------------------------
DATA DIVISION.
WORKING-STORAGE SECTION.
01 GRID-NILAI.
05 BARIS-GRID OCCURS 3 TIMES.
10 NILAI-SEL PIC 9(2) OCCURS 4 TIMES.
01 I PIC 9(2).
01 J PIC 9(2).
PROCEDURE DIVISION.
UTAMA.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 3
PERFORM VARYING J FROM 1 BY 1 UNTIL J > 4
COMPUTE NILAI-SEL(I, J) = I * 10 + J
END-PERFORM
END-PERFORM
DISPLAY "Sel (2, 3) : " NILAI-SEL(2, 3)
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 3
DISPLAY "Baris " I " : "
NILAI-SEL(I, 1) " "
NILAI-SEL(I, 2) " "
NILAI-SEL(I, 3) " "
NILAI-SEL(I, 4)
END-PERFORM
STOP RUN.Sel (2, 3) : 23
Baris 01 : 11 12 13 14
Baris 02 : 21 22 23 24
Baris 03 : 31 32 33 34Pengisian dilakukan oleh sepasang PERFORM VARYING yang bersarang, sehingga setiap
kombinasi I dan J diproses tepat satu kali. Rumus I * 10 + J
dipilih agar pola posisi setiap sel langsung terbaca dari keluarannya, misalnya
sel dengan subskrip (2, 3) bernilai 23. Penelusuran per baris pada perulangan
terakhir memperlihatkan cara membaca satu dimensi secara utuh sementara dimensi
lainnya dikunci pada satu nilai.
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan
./dimensi-dua.
# kompilasi program tabel berdimensi dua
cobc -x dimensi-dua.cblKesalahan umum#
- Mengira penomoran elemen berbasis nol. Subskrip literal nol seperti
NILAI-HARI(0)ditolak saat kompilasi, sedangkan subskrip variabel yang bernilai nol tidak diperiksa dan membaca byte yang berada sebelum tabel tanpa peringatan apa pun. Mulai perulangan dari 1 dan akhiri pada jumlah pengulangannya. - Menghitung ukuran record tanpa memperhitungkan pengulangan. Record
REKAMAN-KELASbukan berukuran 11 byte melainkan 33 byte karena ukuran record level 01 mencakup seluruh pengulangan di dalamnya. Kesalahan ini muncul saat menaksir kebutuhan memori atau membaca record ber-OCCURS dari berkas. - Menuliskan OCCURS pada level 01. Standar COBOL tidak mengizinkan OCCURS pada entri level 01, dan pola yang benar adalah record 01 tanpa OCCURS yang membungkus item level 05 ber-OCCURS. GnuCOBOL menerima bentuk level 01 sebagai perluasan, tetapi kebiasaan tersebut menurunkan portabilitas program.
Ringkasan#
- OCCURS n TIMES mengulang satu definisi item menjadi tabel berukuran tetap, dan setiap elemennya diakses dengan subskrip berbasis satu yang boleh berupa literal maupun variabel.
- Tabel dari grup, yaitu item level 05 ber-OCCURS yang memuat beberapa field anak, merupakan pola paling lazim untuk mendaftar record dengan banyak field.
- Ukuran tabel dihitung dari jumlah pengulangan dikalikan ukuran satu elemen, dan dimensi dua ditulis sebagai OCCURS bersarang yang diakses dengan satu subskrip per dimensi.
Referensi#
- GnuCOBOL Manual — Free Software Foundation — Memuat klausa OCCURS pada pembahasan data description entry beserta aturan subskrip dan penomoran elemennya.
- IBM Enterprise COBOL for z/OS documentation — IBM — Halaman OCCURS clause menjelaskan tabel berdimensi satu dan banyak beserta aturan penomoran elemennya.