Laporan batch pada umumnya mengelompokkan baris menurut kunci tertentu, misalnya kelas, wilayah, atau jenis layanan. Topik ini membahas teknik pemisah kontrol (control break) untuk menyusun laporan semacam itu, yaitu deteksi perubahan kunci grup, pencetakan header grup, perhitungan subtotal, dan perhitungan total akhir. Setelah membacanya, laporan bertingkat dari berkas terurut dapat dihasilkan dalam satu kali pembacaan berkas, lengkap dengan subtotal per grup dan total keseluruhan.
Konsep pemisah kontrol#
Pemisah kontrol (control break) adalah peristiwa berubahnya nilai kunci grup pada berkas yang terurut menurut kunci tersebut. Berkas transaksi memuat baris-baris detail yang sudah diurutkan menurut kunci grup, misalnya kode kelas. Program menyimpan kunci grup yang sedang diproses pada sebuah variabel penahan, kemudian membandingkan kunci setiap rekaman baru dengan variabel itu. Ketika keduanya berbeda, satu pemisah terjadi, yaitu saat subtotal grup lama dicetak, header grup baru dibentuk, dan akumulator subtotal dikembalikan ke nol.
Alur kerjanya sama untuk berkas sekuensial apa pun.
- Baca rekaman perdana sebelum perulangan, salin kuncinya ke variabel penahan, dan cetak header grup pertama.
- Selama rekaman berikutnya berkunci sama, cetak baris detailnya dan tambahkan nilai yang dihitung ke subtotal grup.
- Ketika kunci berubah, cetak subtotal grup lama, salin kunci baru ke variabel penahan, cetak header grup baru, dan nolkan subtotal.
- Setelah berkas habis dibaca, cetak subtotal grup terakhir, kemudian cetak total keseluruhan.
Tiga variabel kerja menopang alur tersebut, yaitu variabel penahan kunci, akumulator subtotal, dan akumulator total. Akumulator total ditambah pada setiap baris detail, sedangkan akumulator subtotal hanya berlaku selama satu grup. Kedua akumulator dideklarasikan dengan PIC 9(3), sehingga nilai terbesar yang dapat ditampung adalah 999 dan ukurannya perlu diperbesar bila datanya lebih besar dari itu.
Syarat keterurutan berkas bukan formalitas. Deteksi pemisah hanya membandingkan kunci berurutan, sehingga kelompok dengan kunci sama yang terpecah pada dua bagian berkas dianggap dua kelompok berbeda. Aturan sederhana ini membuat program tidak perlu menampung seluruh berkas di memori, dan itulah sebabnya teknik ini layak dipakai untuk berkas berukuran besar.
Perulangan bersarang pada PROCEDURE DIVISION#
Struktur PERFORM yang sesuai untuk pola ini adalah dua perulangan bersarang. Perulangan luar berjalan sampai akhir berkas, sedangkan perulangan dalam berjalan selama kunci rekaman masih sama dengan variabel penahan. Akhir berkas ditandai level 88 bernama SELESAI, sehingga kondisi perulangan cukup ditulis UNTIL SELESAI.
Pembacaan rekaman di dalam perulangan hanya terjadi pada satu tempat, yaitu di ujung perulangan dalam, sedangkan rekaman perdana dibaca sebelum perulangan dimulai. Pola ini menjamin setiap rekaman diproses tepat satu kali, baik oleh percabangan deteksi pemisah maupun oleh pencetakan baris detail. Tanpa pola seragam seperti ini, rekaman pertama tiap grup mudah tercetak dua kali atau justru terlewat.
Angka pada keluaran diformat melalui variabel teredit (edited field), yaitu variabel yang picture-nya memuat huruf Z. Huruf Z menekan nol di depan dengan menggantinya menjadi spasi, sehingga nilai 9 tampil sebagai 9 dan bukan 009. Penampilan semacam ini penting pada laporan karena deretan nol di depan mempersulit pembacaan, sementara perhitungan tetap berlangsung pada variabel numerik biasa sebelum dipindahkan ke variabel teredit.
Data dan program#
Data contoh berisi catatan jam piket siswa dari tiga kelas. Setiap baris berukuran 12 karakter, terdiri atas kode kelas tiga karakter, satu spasi, nama lima karakter, satu spasi, dan jam piket dua digit. Berkas sudah terurut menurut kelas, sesuai syarat pemisah kontrol. Struktur FD memecah setiap baris menjadi lima field sesuai posisi kolomnya, dan dua field FILLER menampung spasi pemisah yang tidak diproses. Field yang tidak diproses tetap wajib dideklarasikan agar posisi field berikutnya tidak bergeser.
10A ALI 03
10A BUDI 02
10A CITRA 04
10B DEWI 05
10B EKA 01
10C FAJAR 02
10C GITA 03Program berikut membaca berkas tersebut dan mencetak laporan lengkap dengan subtotal per kelas.
IDENTIFICATION DIVISION.
PROGRAM-ID. LAPORAN-PIKET.
*> Rekap jam piket dengan pemisah kontrol per kelas.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT DATA-PIKET ASSIGN TO "piket.dat"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD DATA-PIKET.
01 REK-PIKET.
05 RP-KELAS PIC X(3).
05 FILLER PIC X.
05 RP-NAMA PIC X(5).
05 FILLER PIC X.
05 RP-JAM PIC 9(2).
WORKING-STORAGE SECTION.
01 WS-EOL PIC X VALUE "N".
88 SELESAI VALUE "Y".
01 WS-KUNCI PIC X(3).
01 WS-SUBTOTAL PIC 9(3) VALUE 0.
01 WS-TOTAL PIC 9(3) VALUE 0.
01 WS-JAM-ED PIC Z9.
01 WS-SUB-ED PIC ZZ9.
01 WS-TOT-ED PIC ZZ9.
PROCEDURE DIVISION.
UTAMA.
OPEN INPUT DATA-PIKET
DISPLAY "REKAP JAM PIKET SISWA"
DISPLAY "====================="
READ DATA-PIKET
AT END MOVE "Y" TO WS-EOL
END-READ
PERFORM UNTIL SELESAI
MOVE RP-KELAS TO WS-KUNCI
DISPLAY " "
DISPLAY "Kelas " WS-KUNCI
PERFORM UNTIL SELESAI
OR RP-KELAS NOT = WS-KUNCI
PERFORM CETAK-BARIS
ADD RP-JAM TO WS-SUBTOTAL WS-TOTAL
READ DATA-PIKET
AT END MOVE "Y" TO WS-EOL
END-READ
END-PERFORM
PERFORM CETAK-SUBTOTAL
END-PERFORM
MOVE WS-TOTAL TO WS-TOT-ED
DISPLAY " "
DISPLAY "Total keseluruhan : " WS-TOT-ED
CLOSE DATA-PIKET
STOP RUN.
CETAK-BARIS.
MOVE RP-JAM TO WS-JAM-ED
DISPLAY " " RP-NAMA " " WS-JAM-ED.
CETAK-SUBTOTAL.
MOVE WS-SUBTOTAL TO WS-SUB-ED
DISPLAY " Subtotal " WS-KUNCI " : " WS-SUB-ED
MOVE 0 TO WS-SUBTOTAL.REKAP JAM PIKET SISWA
=====================
Kelas 10A
ALI 3
BUDI 2
CITRA 4
Subtotal 10A : 9
Kelas 10B
DEWI 5
EKA 1
Subtotal 10B : 6
Kelas 10C
FAJAR 2
GITA 3
Subtotal 10C : 5
Total keseluruhan : 20Kompilasi program dengan perintah berikut, kemudian jalankan ./laporan.
# kompilasi program laporan pemisah kontrol
cobc -x laporan.cblKeluaran memperlihatkan tiga grup, yaitu kelas 10A, 10B, dan 10C. Baris Subtotal tercetak setiap kali perulangan dalam berakhir, baik karena nilai RP-KELAS berbeda dari WS-KUNCI maupun karena berkas habis. Baris Total keseluruhan hanya tercetak satu kali pada akhir laporan. Angka 9, 6, dan 5 merupakan penjumlahan jam tiap kelas, sedangkan 20 adalah jumlah seluruhnya. Perbandingan RP-KELAS NOT = WS-KUNCI pada perulangan dalam menjadi titik terjadinya pemisah, sedangkan perulangan luar berhenti ketika SELESAI bernilai benar.
Kesalahan umum#
- Berkas tidak terurut menurut kunci. Kelompok yang sama terpecah menjadi beberapa header dengan subtotal yang keliru. Urutkan berkas terlebih dahulu, misalnya dengan verb SORT atau utilitas sort, sebelum laporan dijalankan.
- Subtotal grup terakhir terlupa. Percabangan pemisah hanya berjalan saat kunci berubah, sehingga grup terakhir tidak pernah ditutup. Cetak subtotalnya di luar perulangan, tepat sebelum total dicetak.
- Kunci baru tidak disalin ke variabel penahan. Perbandingan terus mendeteksi perubahan pada setiap rekaman, sehingga header dan subtotal tercetak berulang. Salin kunci baru ke variabel penahan segera setelah pemisah ditangani.
Ringkasan#
- Pemisah kontrol mendeteksi perubahan kunci grup pada berkas terurut dan menutup tiap grup dengan subtotal.
- Variabel penahan kunci, akumulator subtotal, dan akumulator total adalah tiga variabel kerja utamanya.
- Perulangan luar menjangkau seluruh berkas, sedangkan perulangan dalam menjangkau satu grup berkunci sama.
- Subtotal grup terakhir dicetak setelah perulangan berakhir, karena tidak ada perubahan kunci yang memicunya.
Referensi#
- GnuCOBOL — Free Software Foundation — Situs proyek GnuCOBOL 3.2, implementasi COBOL sumber terbuka yang dijalankan untuk menghasilkan keluaran pada topik ini.
- GnuCOBOL Manual — Free Software Foundation — Manual resmi GnuCOBOL yang mencakup penggunaan cobc dan pilihan kompilasi program contoh.
- IBM Enterprise COBOL for z/OS documentation — IBM — Dokumentasi resmi pemrosesan berkas sekuensial dan pernyataan kontrol pada COBOL komputer pusat.