Klausa OCCURS DEPENDING ON membuat panjang tabel ditentukan oleh sebuah item pengendali saat program berjalan, sehingga satu definisi dapat menampung daftar yang jumlah entriannya berubah-ubah. Topik ini membahas sintaks klausanya, aturan penempatan item pengendali, perubahan panjang record yang mengikutinya, dan jebakan yang timbul saat pengendali tidak dikelola dengan benar. Contoh utamanya berupa daftar belanja yang diisi tiga entri, lalu ditampilkan dua kali dengan panjang yang berbeda.
Sintaks dan aturan penempatan pengendali#
Bentuk klausanya adalah OCCURS 1 TO 8 TIMES DEPENDING ON JUMLAH-BELI, yang
menyatakan panjang minimum, panjang maksimum, dan nama pengendalinya. Memori
yang dialokasikan tetap sebesar panjang maksimum, sedangkan panjang efektif
record mengikuti nilai pengendali pada saat itu. Item pengendali wajib berupa
bilangan bulat tanpa tanda dan wajib dideklarasikan sebelum item ber-OCCURS di
dalam kode sumber, biasanya sebagai record 01 tersendiri atau sebagai field yang
mendahului tabel di dalam record yang sama. Aturan urutan ini berlaku umum pada
compiler COBOL, dan pelanggarannya ditolak dengan pesan seperti
error: 'JUMLAH-X' OCCURS DEPENDING ON field item invalid here.
Item yang ditempatkan setelah tabel ber-OCCURS DEPENDING ON di dalam record yang sama akan bergeser posisi setiap kali pengendali berubah. Karena itu, tabel ber-OCCURS DEPENDING ON lazim diletakkan paling akhir di dalam recordnya, dan field yang harus tetap pada tempatnya dipisahkan ke record lain. Pengendali juga tidak boleh menjadi bagian dari tabel, karena posisi field di dalam tabel itu bergantung pada panjang tabelnya.
Nilai pengendali dapat berubah berkali-kali selama program berjalan, dan setiap perubahan langsung mengatur ulang panjang efektif record. Byte milik elemen di luar panjang efektif tetap berada di memori, tetapi tidak lagi dianggap bagian record sehingga tidak layak dibaca. Pemindahan record ber-OCCURS DEPENDING ON ke record lain yang strukturnya sama hanya memindahkan data sepanjang panjang efektifnya saat itu. Sifat ini pula yang membuat klausanya banyak dipakai untuk record berpanjang variabel pada berkas, yang jumlah kemunculannya baru diketahui setelah data dibaca.
Daftar belanja dengan panjang dinamis#
Program berikut menyimpan daftar belanja yang panjangnya dikendalikan oleh
JUMLAH-BELI. Tiga entri diisi terlebih dahulu, seluruh entri ditampilkan
melalui perulangan yang batasnya adalah pengendali itu sendiri, lalu pengendali
diturunkan menjadi 2 dan daftar yang sama ditampilkan kembali.
IDENTIFICATION DIVISION.
PROGRAM-ID. ODO-BELANJA.
*--------------------------------------------------------------
* OCCURS DEPENDING ON: panjang tabel mengikuti pengendali.
*--------------------------------------------------------------
DATA DIVISION.
WORKING-STORAGE SECTION.
01 JUMLAH-BELI PIC 9(2) VALUE 3.
01 DAFTAR-BELANJA.
05 ITEM-BELI OCCURS 1 TO 8 TIMES
DEPENDING ON JUMLAH-BELI.
10 NAMA-BELI PIC X(10).
10 BANYAK-BELI PIC 9(2).
01 I PIC 9(2).
PROCEDURE DIVISION.
UTAMA.
MOVE "Buku Tulis" TO NAMA-BELI(1)
MOVE 4 TO BANYAK-BELI(1)
MOVE "Pensil " TO NAMA-BELI(2)
MOVE 6 TO BANYAK-BELI(2)
MOVE "Penghapus" TO NAMA-BELI(3)
MOVE 2 TO BANYAK-BELI(3)
PERFORM TAMPIL-SATU
VARYING I FROM 1 BY 1 UNTIL I > JUMLAH-BELI
MOVE 2 TO JUMLAH-BELI
DISPLAY "Pengendali kini " JUMLAH-BELI
PERFORM TAMPIL-SATU
VARYING I FROM 1 BY 1 UNTIL I > JUMLAH-BELI
STOP RUN.
TAMPIL-SATU.
DISPLAY "Elemen " I " : " NAMA-BELI(I) "|"
BANYAK-BELI(I).Elemen 01 : Buku Tulis|04
Elemen 02 : Pensil |06
Elemen 03 : Penghapus |02
Pengendali kini 02
Elemen 01 : Buku Tulis|04
Elemen 02 : Pensil |06Isi tabel tidak berubah di antara kedua penampilan, tetapi baris ketiga hilang
pada penampilan kedua karena panjang efektif DAFTAR-BELANJA kini mengikuti
nilai 2. Perulangan yang batasnya I > JUMLAH-BELI berhenti dengan sendirinya
pada batas baru tersebut. Pola inilah yang membuat OCCURS DEPENDING ON cocok
untuk data berpanjang variabel seperti baris transaksi pada satu nota, yang
jumlahnya baru diketahui ketika data dibaca.
Urutan langkah yang aman untuk tabel semacam ini adalah mengisi pengendali
terlebih dahulu, mengisi elemen pada subskrip 1 sampai nilai pengendali, lalu
menelusurinya dengan batas yang sama. Pada program di atas, JUMLAH-BELI sudah
bernilai 3 sejak deklarasi melalui klausa VALUE, sehingga pengisiannya langsung
sah. Apabila daftar dibaca dari luar program, nilai pengendali diisi dari data
tersebut sebelum elemen pertama ditulis. Disiplin yang sama berlaku saat panjang
daftar bertambah, yaitu naikkan pengendalinya setelah entri barunya terisi.
Elemen keempat sampai kedelapan pada program ini tetap menempati memori karena
alokasinya mengikuti panjang maksimum, tetapi byte tersebut berada di luar
panjang efektif selama pengendali bernilai 2.
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./odo.
# kompilasi program tabel panjang variabel
cobc -x odo.cblKesalahan umum#
- Meletakkan pengendali setelah tabel ber-OCCURS DEPENDING ON. Aturan urutan
deklarasi menuntut pengendali mendahului tabelnya, dan pelanggarannya ditolak
compiler dengan pesan
error: 'JUMLAH-X' OCCURS DEPENDING ON field item invalid here. Pindahkan pengendali ke record 01 tersendiri atau ke field sebelum tabel. - Mengakses tabel sebelum pengendali diisi. Field
PIC 9(2)tanpa VALUE berisi spasi, sehingga kondisi sepertiI > JUMLAH-BELItidak dapat dievaluasi dengan benar dan panjang record menjadi tidak sah. Isi pengendali lebih dahulu, atau beri nilai awal melalui klausa VALUE. - Membaca elemen melebihi nilai pengendali. Akses seperti
NAMA-BELI(5)saat pengendali bernilai 3 tidak ditolak, tetapi byte yang dibaca bukan bagian dari record yang sah dan berisi sisa memori. Gunakan nilai pengendali sebagai batas atas setiap penelusuran. - Menganggap posisi item setelah tabel tidak berubah. Item yang menyusul tabel ber-OCCURS DEPENDING ON di dalam record yang sama ikut bergeser setiap kali pengendali berubah, sehingga pembacaan field tersebut perlu dilakukan setelah pengendali bernilai final. Letakkan tabel di akhir record atau pisahkan fieldnya.
Ringkasan#
- OCCURS n TO m TIMES DEPENDING ON mengalokasikan memori sebesar panjang maksimum, sedangkan panjang efektif record mengikuti nilai pengendali saat program berjalan.
- Pengendali wajib berupa bilangan bulat tanpa tanda yang dideklarasikan sebelum item ber-OCCURS, dan item yang menyusul tabel di dalam record yang sama ikut bergeser saat pengendali berubah.
- Setiap akses tabel perlu pengendali yang sudah terisi dan subskrip yang tidak melebihi nilai pengendali, karena di luar itu isi byte tidak terdefinisi.
Referensi#
- GnuCOBOL Manual — Free Software Foundation — Memuat klausa OCCURS DEPENDING ON beserta aturan penempatan item pengendalinya.
- IBM Enterprise COBOL for z/OS documentation — IBM — Halaman OCCURS clause dengan DEPENDING ON menjelaskan record panjang variabel dan batasan penempatan pengendalinya.