Number Range Management (SNRO & Modern APIs)
Target: ABAP Developer (Lanjutan)
Prasyarat: Modul 2: ABAP Dictionary, Modul 5: Modularization
Lingkungan: SAP NetWeaver, SAP S/4HANA, SAP BTP ABAP Environment
Gambaran Umum
Setiap dokumen transaksi bisnis di sistem SAP (seperti Sales Order SO-2026-0001, Faktur Pajak, atau Material Document) membutuhkan pengenal unik (unique primary key) berupa nomor berurutan.
Dalam arsitektur enterprise dengan ratusan pengguna atau antarmuka API yang membuat transaksi secara serentak di detik yang sama, menghasilkan nomor urut yang unik, berurutan, dan bebas dari tabrakan data (concurrency-safe) adalah persoalan krusial yang tidak boleh diselesaikan dengan query biasa.
Number Range Object adalah fasilitas resmi bawaan kernel SAP untuk mengelola dan menerbitkan nomor urut dokumen secara aman, berkinerja tinggi, dan mendukung kepatuhan hukum (audit compliance).
Daftar Isi
π’ Fundamental
- Mengapa Penomoran Otomatis Membutuhkan Penanganan Khusus
- Jebakan Fatal Logika SELECT MAX + 1 (Race Condition)
- Konsep Dasar: Penomoran Internal vs Eksternal
- Konfigurasi Number Range Object di T-Code SNRO
π‘ Lanjutan
- Konsep Buffering Memori vs No-Buffering (Gapless Numbering)
- Implementasi On-Premise Klasik: Function Module NUMBER_GET_NEXT
- Implementasi Modern di ABAP Cloud: Class CL_NUMBERRANGE_RUNTIME
- Penomoran Dokumen pada RAP: Early vs Late Numbering
- Penanganan Error & Exception: INTERVAL_NOT_FOUND & Batas Kritis
π οΈ Praktik & Rujukan
- Praktik: Konfigurasi Objek Penomoran Faktur & Pemanggilan Kode ABAP
- Ringkasan & Cheat Code Number Range
- Referensi Resmi
1. π’ Mengapa Penomoran Otomatis Membutuhkan Penanganan Khusus
Di luar sistem enterprise, developer pemula sering menggunakan kolom auto-increment bawaan database atau menghitung nilai maksimum tabel. Di lingkungan SAP, pendekatan tersebut dilarang karena:
- Mengharuskan penguncian tabel database skala penuh (table locking) yang memperlambat seluruh pengguna.
- Tidak mendukung pemisahan nomor per entitas bisnis (misal: penomoran faktur berbeda untuk Company Code
1000vs2000). - Tidak mendukung aturan regulasi perpajakan yang menuntut nomor urut tanpa celah (gapless numbering) per tahun fiskal.
2. π’ Jebakan Fatal Logika SELECT MAX + 1 (Race Condition)
Banyak pengembang pemula tergoda menuliskan logika seperti ini:
" KODE SALAH & SANGAT BERBAHAYA:
SELECT MAX( order_id ) FROM ztsales_order INTO @DATA(lv_max_id).
lv_new_id = lv_max_id + 1.
INSERT INTO ztsales_order VALUES @(...).Mengapa Logika di Atas Fatal? (Race Condition)
Waktu | Transaksi User A (Kasir 1) | Transaksi User B (Kasir 2)
ββββββββΌββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ
10:00 | SELECT MAX -> Menemukan ID: 100 |
10:01 | | SELECT MAX -> Menemukan ID: 100
10:02 | lv_new_id = 100 + 1 = 101 | lv_new_id = 100 + 1 = 101
10:03 | INSERT ID: 101 (SUKSES) |
10:04 | | INSERT ID: 101 (CRASH DUMP DUPLICATE KEY!)Jika dua pengguna atau dua request web API menekan tombol simpan secara bersamaan, keduanya membaca nilai maksimum yang sama (100). Akibatnya, transaksi kedua mengalami crash fatal runtime (Short Dump DBSQL_DUPLICATE_KEY_ERROR).
3. π’ Konsep Dasar: Penomoran Internal vs Eksternal
Saat mendefinisikan interval penomoran di SAP:
| Tipe Penomoran | Mekanisme Pembuatan | Penanda di SAP | Contoh Kasus |
|---|---|---|---|
| Internal Numbering | Sistem SAP secara otomatis mengambil nomor urut berikutnya dari memori tanpa input user. | Kolom EXT tidak dicentang. | Nomor Dokumen Akuntansi (10000001), Sales Order (50000012). |
| External Numbering | Pengguna atau sistem luar wajib mengetikkan ID secara manual, namun sistem memeriksa apakah ID berada di dalam rentang yang sah. | Kolom EXT dicentang. | Kode Material kustom (MAT-A01), Nomor Faktur Pajak dari kantor pajak. |
4. π’ Konfigurasi Number Range Object di T-Code SNRO
T-Code SNRO (atau SNUM) digunakan untuk membuat objek penomoran di Data Dictionary:
Atribut Konfigurasi SNRO:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Object Name: ZORD_NUM (Nomor Pesanan Penjualan) β
β Short Text : Objek Penomoran Pesanan β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β’ Number Length Domain : CHAR10 (Panjang digit maksimal) β
β β’ Warning Percentage : 10% (Peringatan saat nomor sisa 10%)β
β β’ Subobject Data Elem. : BUKRS (Pemisahan per Company Code) β
β β’ To-year Flag : X (Penomoran di-reset per tahun) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Tombol 'Number Ranges' (Interval): β
β No | Tahun | Rentang Awal | Rentang Akhir | Status Saat Iniβ
β 01 | 2026 | 0001000000 | 0001999999 | 0001000045 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ- To-year Flag: Jika dicentang, interval dapat didefinisikan berbeda untuk setiap tahun kalender (misal: tahun 2026 mulai dari
1, tahun 2027 mulai dari1lagi). - Subobject: Memungkinkan penomoran independen berdasarkan field tertentu (misal: nomor faktur mandiri per cabang/Company Code).
5. π‘ Konsep Buffering Memori vs No-Buffering (Gapless Numbering)
Pada konfigurasi SNRO, pilihan mekanisme Buffering membawa konsekuensi arsitektural yang sangat penting:
1. Main Memory Buffering (Sangat Cepat - Standar):
Application Server meminjam 10-100 nomor sekaligus ke dalam RAM (Shared Buffer).
[User 1: ambil 101] -> [User 2: ambil 102] -> Tidak menyentuh database disk!
RISIKO: Jika server listrik padam atau di-restart, sisa nomor di RAM HILANG (Gaps).
2. No Buffering / Gapless (Ketat Tanpa Celah - Hukum Akuntansi):
Setiap permintaan nomor mengunci baris tabel NRIV di database secara langsung.
KEUNGGULAN: Dijamin 100% urut tanpa ada angka yang melompat (1, 2, 3, 4, 5).
RISIKO: Menjadi titik kemacetan (Bottleneck) performa jika ribuan user mengakses serentak.- Gunakan No Buffering hanya untuk nomor faktur legal atau dokumen finansial resmi yang diaudit kantor pajak.
- Gunakan Main Memory Buffering untuk dokumen operasional biasa (Sales Order, Purchase Requisition, IDoc log).
6. π‘ Implementasi On-Premise Klasik: Function Module NUMBER_GET_NEXT
Pada program ABAP klasik dan S/4HANA On-Premise, penomoran diambil menggunakan Function Module resmi NUMBER_GET_NEXT:
DATA: lv_new_number TYPE c LENGTH 10,
lv_returncode TYPE inri-returncode.
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = '01' " Nomor Interval
object = 'ZORD_NUM' " Nama Objek SNRO
subobject = '1000' " Company Code (jika ada)
toyear = '2026' " Tahun Fiskal (jika ada)
IMPORTING
number = lv_new_number
returncode = lv_returncode
EXCEPTIONS
interval_not_found = 1
number_range_not_intern = 2
object_not_found = 3
quantity_is_0 = 4
quantity_not_1 = 5
interval_overflow = 6
buffer_overflow = 7
OTHERS = 8.
IF sy-subrc = 0.
WRITE: / 'Nomor Dokumen Baru Berhasil Diterbitkan:', lv_new_number.
IF lv_returncode = '1'.
WRITE: / 'PERINGATAN: Nomor urut pada interval ini hampir habis!'.
ENDIF.
ELSE.
WRITE: / 'Gagal mengambil nomor urut. Error Code:', sy-subrc.
ENDIF.7. π‘ Implementasi Modern di ABAP Cloud: Class CL_NUMBERRANGE_RUNTIME
Pada model ABAP Cloud (SAP BTP ABAP Environment dan SAP S/4HANA Cloud Public Edition), Function Module klasik NUMBER_GET_NEXT bukan merupakan Released API.
SAP menyediakan kelas pengganti resmi yang berstatus Released: CL_NUMBERRANGE_RUNTIME:
" SINTAKS RESMI ABAP CLOUD:
TRY.
cl_numberrange_runtime=>number_get(
EXPORTING
nr_range_nr = '01'
object = 'ZORD_NUM'
quantity = 1
IMPORTING
number = DATA(lv_number)
returncode = DATA(lv_retcode)
returned_quantity = DATA(lv_qty)
).
" Nomor baru siap digunakan secara type-safe
DATA(lv_order_id) = CONV string( lv_number ).
CATCH cx_nr_object_not_found INTO DATA(lx_obj).
" Tangani objek SNRO tidak terdaftar
CATCH cx_number_ranges INTO DATA(lx_nr).
" Tangani error umum interval penuh atau terkunci
ENDTRY.8. π‘ Penomoran Dokumen pada RAP: Early vs Late Numbering
Pada kerangka kerja modern SAP RAP (RESTful Application Programming), penomoran entitas dikelola secara deklaratif di file Behavior Definition (.bdef):
- Early Numbering:
- Nomor langsung diterbitkan saat pengguna mengklik tombol Create di layar Fiori.
- Cocok jika pengguna perlu melihat nomor ID dokumen sebelum menekan tombol Save.
- Late Numbering:
- Nomor baru diterbitkan di akhir transaksi tepat saat fase Finalize / Save ke database.
- Sangat direkomendasikan untuk menghindari nomor hangus/gaps jika pengguna membatalkan pembuatan transaksi di tengah jalan!
// Definisi pada BDEF RAP:
managed implementation in class zbp_i_order unique;
define behavior for ZI_SalesOrder_R alias Order
late numbering // Penomoran otomatis saat fase simpan permanen
persistent table ztsales_order
{
create;
update;
delete;
}9. π‘ Penanganan Error & Exception: INTERVAL_NOT_FOUND & Batas Kritis
Dua insiden operasional yang paling sering terjadi pada Number Range:
INTERVAL_NOT_FOUND:- Penyebab: Tahun kalender berganti (misal tanggal 1 Januari 2027), namun administrator belum mendaftarkan interval untuk tahun
2027. - Solusi: T-Code
SNROTambahkan interval untuk tahun buku baru.
- Penyebab: Tahun kalender berganti (misal tanggal 1 Januari 2027), namun administrator belum mendaftarkan interval untuk tahun
- Interval Overflow (Nomor Habis):
- Penyebab: Nomor status saat ini sudah mencapai rentang akhir (misal
999999). - Pencegahan: Pantau parameter
returncode = '1'(Warning threshold tercapai) untuk memperluas rentang digit sebelum transaksi macet total.
- Penyebab: Nomor status saat ini sudah mencapai rentang akhir (misal
10. π οΈ Praktik: Konfigurasi Objek Penomoran Faktur & Pemanggilan Kode ABAP
Skenario Bisnis
Kita ingin membangun program pencatat pesanan ZREP_GENERATE_ORDER_ID yang menerbitkan nomor ID transaksi berformat otomatis SO-2026-XXXXXX menggunakan objek Number Range ZORD_DEMO.
Langkah 1: Simulasi Konfigurasi di T-Code SNRO
- Buka T-Code
SNROObjek:ZORD_DEMO. - Domain:
CHAR8(8 digit). - Klik tombol Number Ranges Change Intervals Tambah Interval:
- No:
01 - From:
00000001 - To:
00099999 - Ext: [ ] (Kosongkan agar menjadi penomoran otomatis/Internal).
- No:
- Simpan perubahan.
Langkah 2: Kode Program Penerbit Nomor Dokumen
*&---------------------------------------------------------------------*
*& Report ZREP_GENERATE_ORDER_ID
*&---------------------------------------------------------------------*
*& Demonstrasi Pengambilan Nomor Dokumen Unik Menggunakan SNRO
*&---------------------------------------------------------------------*
REPORT zrep_generate_order_id LINE-SIZE 85.
DATA: lv_raw_num TYPE c LENGTH 8,
lv_retcode TYPE inri-returncode,
lv_full_id TYPE string.
START-OF-SELECTION.
WRITE: / sy-uline(80).
WRITE: / '|', (76) 'SISTEM PENERBITAN NOMOR DOKUMEN TRANSAKSI RESMI (SNRO)' CENTERED, '|'.
WRITE: / sy-uline(80).
" Mengambil nomor urut otomatis berikutnya yang bebas dari tabrakan konkurensi:
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = '01'
object = 'ZORD_DEMO'
IMPORTING
number = lv_raw_num
returncode = lv_retcode
EXCEPTIONS
interval_not_found = 1
number_range_not_intern = 2
object_not_found = 3
OTHERS = 4.
IF sy-subrc = 0.
" Memformat nomor menjadi kode dokumen bisnis yang profesional
lv_full_id = |SO-{ sy-datum(4) }-{ lv_raw_num }|.
WRITE: / '| Status Pengambilan : SUKSES (Concurrency-Safe)', (38) ' ', '|',
/ '| Nomor Mentah SNRO :', (15) lv_raw_num, (41) ' ', '|',
/ '| ID Dokumen Resmi :', (25) lv_full_id, (31) ' ', '|'.
IF lv_retcode = '1'.
WRITE: / '| PERINGATAN : Sisa kapasitas nomor interval < 10%!', (26) ' ', '|'.
ENDIF.
ELSE.
WRITE: / '| STATUS : GAGAL! Nomor interval belum dikonfigurasi di T-Code SNRO.', (13) ' ', '|'.
ENDIF.
WRITE: / sy-uline(80).Hasil Eksekusi
---------------------------------------------------------------------------------
| SISTEM PENERBITAN NOMOR DOKUMEN TRANSAKSI RESMI (SNRO) |
---------------------------------------------------------------------------------
| Status Pengambilan : SUKSES (Concurrency-Safe) |
| Nomor Mentah SNRO : 00000105 |
| ID Dokumen Resmi : SO-2026-00000105 |
---------------------------------------------------------------------------------11. π Ringkasan & Cheat Code Number Range
Peta Konsep
Manajemen Number Range
βββ 1. Bahaya Konkurensi
β βββ Hindari SELECT MAX + 1 (Memicu tabrakan duplikasi key saat multi-user)
βββ 2. Karakteristik Interval (SNRO)
β βββ Internal (Otomatis oleh sistem)
β βββ External (Diisi manual oleh user/sistem luar)
βββ 3. Pilihan Buffering
β βββ Main Memory Buffering (Cepat di RAM, nomor bisa melompat/gaps)
β βββ No Buffering (Terkunci di disk NRIV, lambat, mutlak tanpa celah)
βββ 4. Konsumsi API
βββ On-Premise Klasik : Function Module NUMBER_GET_NEXT
βββ ABAP Cloud Modern : Class CL_NUMBERRANGE_RUNTIME=>NUMBER_GET
βββ SAP RAP : Deklarasi 'late numbering' pada BDEFCheat Code T-Code 10 Detik
SNRO / SNUM β Konfigurasi Number Range Object & interval batas penomoran
NRIV β Tabel database fisik tempat seluruh interval penomoran disimpan