BILLIB/i is an ILE COBOL customer-billing / general-ledger reference application:
a batch billing cycle that discounts each open invoice, updates the customer's balance and posts
balanced GL entries; a CL-driven online customer-maintenance program reached by parameter; and an
embedded-SQL aging report. It is deliberately a language-reference estate — each program
exists to exercise one facet of ILE COBOL on IBM i (LINKAGE / PROCEDURE DIVISION USING, COBOL→*PGM
CALL, ASSIGN TO DATABASE- with keyed and sequential EXTFH I/O, COPY DDS-ALL-FORMATS,
embedded EXEC SQL, and the CRTCBLMOD+CRTPGM bind path) —
while still reading as a real billing/GL app. This manual serves the operator who runs the cycle and the
developer maintaining the programs. It is grounded entirely in the committed source
(cobol-app/test/billing_cycle.mjs and cobol-app/test/edge_probes.mjs, which
carry the COBOL/DDS/CL source as members plus the driver-computed oracles). Everything runs in library
BILLIB.
BILLIB/i runs the everyday work of a small customer-billing / receivables shop:
BILLPOST reads the invoice header file, and for each
OPEN invoice looks up the customer's class-based discount rate (by calling RATELOOK),
computes the net amount, adds it to the customer's balance, and posts a balanced pair of GL
entries (debit AR, credit revenue). It prints a run report and counts posted vs. bad-customer rows.RATELOOK is a small packed-decimal routine:
class A→10%, class B→5%, else 0%; net = amount − amount×rate/100. It is invoked
COBOL-to-COBOL from BILLPOST by reference.CUSTMNT is reached by parameter:
an action code (Inquire / Update credit limit / Delete), a customer id and a
new limit go in; a file-status and the current balance come back. CUSTMCL is a CL
wrapper that calls it with CALL PARM and echoes the result.AGERPT runs an EXEC SQL cursor over
the invoice file — total open amount per customer, only customers with more than one open
invoice — and DISPLAYs a line each.GLTOTPGM (built via CRTCBLMOD
+ CRTPGM) sequentially counts the GL rows, confirming the posting count.Honest statement: BILLIB/i was built as a reference application that exercises the ILE COBOL layer of the SteelFrame X engine. It is a genuine, self-consistent billing/GL app — the balances, discounts and GL both-sides-net-to-zero are real and hand-checked — but its shape was chosen so each program demonstrates a distinct i-COBOL feature rather than to cover every edge of a production billing system. Two consequences an operator should know up front:
CUSTMNT) has no DDS screen; it is a parameter-driven *PGM reached
by CALL … PARM (from CL, from another program, or from a test driver). Section B
is honest about this.AGERPT) can be exercised independently of the EXTFH
layer. This is a design choice of the reference estate, documented in the source, not a defect.Section F maps each program to the exact ILE COBOL feature it demonstrates.
ONLINE / CL-DRIVEN BATCH (billing cycle) REPORTING
----------------- --------------------- ---------
CUSTMCL (CLP) BILLPOST (CBLLE) AGERPT (CBLLE + EXEC SQL)
CALL PARM OPEN INPUT INVHPF cursor over INVHPF
| OPEN I-O CUSTMPF GROUP BY / HAVING COUNT(*)>1
v OPEN EXTEND GLPF DISPLAY per customer
CUSTMNT (CBLLE) for each OPEN invoice:
LINKAGE / PROCEDURE CALL "RATELOOK" -----> RATELOOK (CBLLE)
DIVISION USING (C-CL IAMT WS-NET) packed-decimal discount
keyed READ/REWRITE/ ADD WS-NET TO C-BAL
DELETE on CUSTMPF REWRITE CUST-REC (keyed I-O)
WRITE GL-REC x2 (AR debit / REV credit)
WRITE report line (PRINTER-QSYSPRT)
|
v
CUSTMPF (balances) GLPF (postings) QSYSPRT (spool)
journaled journaled
BILLJRN / BILLRCV <-- STRJRNPF on GLPF + CUSTMPF
GLTOTMOD --CRTCBLMOD--> *MODULE --CRTPGM--> GLTOTPGM (sequential count of GLPF)
A single billing event flows: BILLPOST reads an OPEN INVHPF row →
keyed-reads the matching CUSTMPF customer → CALLs RATELOOK for the net
amount → ADDs net to the customer balance and REWRITEs the record →
WRITEs two GL rows (net debit to AR1000, net credit to RV2000) → the writes to
GLPF and CUSTMPF land in the BILLJRN journal, and a report line is
spooled to QSYSPRT.
| Object | Type | Role |
|---|---|---|
| CUSTMPF | PF (DDS) | Customer master, UNIQUE keyed on CUSTID. |
| INVHPF | PF (DDS) | Invoice header, arrival sequence. |
| RATEPF | PF (DDS) | Discount-rate table (see D — rate logic lives in RATELOOK). |
| GLPF | PF (DDS) | GL postings, arrival sequence, signed amounts. |
| RATELOOK | CBLLE *PGM | Packed-decimal discount routine; called by BILLPOST. |
| BILLPOST | CBLLE *PGM | Batch billing cycle (the heart of the app). |
| CUSTMNT | CBLLE *PGM | Parameter-driven customer maintenance (I/U/D). |
| CUSTMCL | CLP *PGM | CL wrapper calling CUSTMNT with CALL PARM. |
| AGERPT | CBLLE *PGM | Embedded-SQL aging/aggregation report. |
| GLTOTMOD | *MODULE | CRTCBLMOD module (GL row count). |
| GLTOTPGM | *PGM | CRTPGM-bound program from GLTOTMOD. |
| BILLJRN | Journal | Journals GLPF + CUSTMPF writes. |
| BILLRCV | Jrn receiver | Receiver for BILLJRN. |
| QCBLLESRC | Source PF | ILE COBOL source members. |
| QDDSSRC | Source PF | DDS source members. |
| QCLSRC | Source PF | CL source members. |
The estate is 4 DDS physical files + 6 COBOL/CL programs + 1 bound module/program pair, journaled,
driven from a single job (BILLJOB, user QPGMR). Sections D and F expand each.
BILLIB/i has no CICS transaction identifiers and no menu. On IBM i each program is reached by
name — from a 5250 command-entry line, from a CL program, or from a JOBQ/scheduler for the
batch job. The job's library list must include BILLIB; the tested job runs with
LIBL = QSYS QGPL BILLIB QTEMP and CURLIB = BILLIB (job BILLJOB,
user QPGMR).
| To do this | Type on the command line |
|---|---|
| Run the billing cycle | CALL BILLIB/BILLPOST (or SBMJOB it) |
| Maintain a customer directly (I/U/D) | CALL BILLIB/CUSTMNT PARM(…) |
| Maintain a customer via the CL wrapper | CALL BILLIB/CUSTMCL |
| Run the aging report | CALL BILLIB/AGERPT |
| Reconcile the GL row count | CALL BILLIB/GLTOTPGM |
| Look up the discount net directly | CALL BILLIB/RATELOOK PARM(…) |
BILLPOST, AGERPT and GLTOTPGM take no parameters — a
bare CALL (or SBMJOB) drives them. CUSTMNT and RATELOOK
are parameter programs (see B.2 and F).
CUSTMNT is the closest thing BILLIB/i has to an “online transaction”: a
parameter-driven maintenance program over the customer master. It declares a
LINKAGE SECTION and a PROCEDURE DIVISION USING five parameters, opens
CUSTMPF I-O with ACCESS MODE IS DYNAMIC and
RECORD KEY IS C-ID, keyed-READs the requested customer, and dispatches on the
action code:
| Parameter | PIC | Dir | Meaning |
|---|---|---|---|
| LK-ACTION | X(1) | in | U update credit limit, D delete, other = inquire. |
| LK-CUSTID | X(6) | in | Customer id to act on (moved to key C-ID). |
| LK-NEWLIM | S9(7)V99 COMP-3 | in | New credit limit (used on action U). |
| LK-OUTSTAT | X(2) | out | FILE STATUS of the keyed operation (00 ok, 23 not found). |
| LK-OUTBAL | S9(7)V99 COMP-3 | out | Current customer balance, echoed by reference. |
MOVE LK-NEWLIM TO C-CRLIM, REWRITE CUST-REC,
return status + balance. Verified: ('U','C00002',2500.00) → status 00,
balance 475.00 echoed, and the limit lands as 2500.00 with the balance untouched.DELETE CUSTF RECORD, return status + balance. Verified via the
CL wrapper deleting C00003; a re-delete of the now-missing key returns FILE STATUS
23 (not-found), not a silent success.WS-FS is moved to LK-OUTSTAT and balance is
zeroed — the caller sees the file status rather than stale data.CUSTMCL is the CL front door: it DCLs the five variables, issues
CALL PGM(BILLIB/CUSTMNT) PARM(&ACTION &CUSTID &NEWLIM &OUTSTAT &OUTBAL), then
SNDPGMMSGs CUSTMCL STATUS=[nn] BAL=[amt] — demonstrating the
CL→COBOL CALL PARM path with a numeric *DEC(9 2) and character
parameters passed by reference and read back after the call.
CUSTMNT writes
its results into the caller's LK-OUTSTAT/LK-OUTBAL storage, and the CL
wrapper (or a direct caller) reads the updated values after the CALL returns. The packed
COMP-3 balance survives the CL *DEC↔COBOL COMP-3 boundary.There is no DDS display file and no subfile in BILLIB/i. “Online” here means
parameter-driven, not screen-driven: an operator or a driving program supplies the five parameters and
reads the two output parameters back. There is likewise no maker–checker authorization —
a CUSTMNT update or delete is applied immediately on the keyed file. The control model the
app actually provides is journaling: CUSTMPF (and GLPF) are under
BILLJRN, so every REWRITE/DELETE/WRITE is captured for
after-the-fact audit and recovery. Section E covers the operational use of that trail.
The billing cycle is a single batch program, BILLPOST, plus two supporting programs run
around it (AGERPT for reporting, GLTOTPGM for GL reconciliation). None take
parameters; each is driven by a bare CALL or SBMJOB. The cycle reads its work
from the data itself — every INVHPF row whose ISTAT = 'O' (open) —
so there is no control row to advance; you seed/refresh invoices, then run.
-- submit the (parameterless) billing cycle as a batch job SBMJOB CMD(CALL PGM(BILLIB/BILLPOST)) JOB(BILLPOST) -- then the aging report and GL reconciliation CALL BILLIB/AGERPT CALL BILLIB/GLTOTPGM
| Program | Purpose | Files / calls | Inputs | Outputs |
|---|---|---|---|---|
| BILLPOST | Discount & post every OPEN invoice; update balances; write GL. | INPUT INVHPF (seq); I-O CUSTMPF (keyed); EXTEND GLPF (seq); PRINTER-QSYSPRT; CALL RATELOOK. | OPEN invoices in INVHPF; customer classes in CUSTMPF. | Updated CBAL (REWRITE); 2 GL rows per invoice; report to QSYSPRT; DISPLAY "BILLPOST N=nnn BAD=nnn". |
| AGERPT | Open-amount aggregation per customer (>1 open invoice). | Embedded SQL cursor over INVHPF (GROUP BY/HAVING/ORDER BY); COMMIT. | OPEN invoices in INVHPF. | DISPLAY "AGE cust TOT=amt CNT=n" per qualifying customer, then AGERPT DONE. |
| GLTOTPGM | Count GL postings (reconciliation). | INPUT GLPF (seq). Built CRTCBLMOD→CRTPGM. | GLPF rows. | DISPLAY "GLROWS=n" (expected 8 after a 4-invoice run). |
BILLPOST opens four files with three different I/O disciplines —
OPEN INPUT INVF (sequential), OPEN I-O CUSTF (keyed dynamic),
OPEN EXTEND GLF (append), OPEN OUTPUT RPTF (printer) — then loops the
invoice file. For each ISTAT = 'O' invoice it:
MOVE ICUSTID TO C-ID and keyed-READ CUSTF. If the customer is missing
(WS-CUSTFS ≠ '00') it bumps WS-BADCUST and skips.CALL "RATELOOK" USING C-CL IAMT WS-NET — the discounted net comes back by reference.ADD WS-NET TO C-BAL then REWRITE CUST-REC — the balance update via keyed I-O.WRITE GL-REC twice: AR1000 for +WS-NET (debit) and
RV2000 for 0 - WS-NET (credit) — so every invoice contributes a
balanced pair and the GL nets to zero.STRING a report line (INVNO ICUSTID NET=edited) and WRITE it
to the printer file.At end it prints a POSTED= BADCUST= summary line and DISPLAYs
BILLPOST N=nnn BAD=nnn.
Expected (4 OPEN invoices, all customers present): BILLPOST N=004 BAD=000 C00001 bal = 900.00 + 225.00 = 1125.00 (I00001 + I00003, class A 10%) C00002 bal = 475.00 (I00002, class B 5%) C00003 bal = 720.00 (I00004, class A 10%) GLPF = 8 rows, SUM(GLAMT) = 0.00 (4 debits + 4 credits)
BILLPOST does not flip invoices out of OPEN
status — INVHPF is read-only in this pass by design. Re-running it therefore
re-bills the same invoices (balances grow again, GL doubles). Treat a billing run as a one-shot per
invoice set; to re-run cleanly, reset the seed data first. This is called out in the source comments as
a deliberate reference-estate simplification.edge_probes.mjs ships a second library (EDGELIB, over an ORDPF
orders file) whose programs are not part of the billing cycle but exercise engine corners in COBOL:
ORDRD (a sequential reader ridden by OPNQRYF/QRYSLT then
CLOF), DYNCLR/DYNTGT (dynamic CALL by identifier
variable), CANCTEST/STATEFUL (COBOL CANCEL re-init semantics), and
NEGDISP (negative COMP-3 through a numeric-edited trailing-sign PICTURE). They
are documented for developers in F.5.
All files are DDS physical files in library BILLIB, created with CRTPF from
members in QDDSSRC, and consumed by the COBOL programs via ASSIGN TO DATABASE-
and (for INVHPF) COPY DDS-ALL-FORMATS OF INVHPF. Money fields are packed
9P 2 (COMP-3 in COBOL); ids are fixed Alpha.
| Field | DDS type | COBOL PIC | Meaning |
|---|---|---|---|
| CUSTID | 6A | X(6) | Customer id (unique key), e.g. C00001. |
| CUSTNM | 20A | X(20) | Customer name. |
| CUSTCL | 1A | X(1) | Customer class — drives the discount (A=10%, B=5%, else 0%). |
| CRLIM | 9P 2 | S9(7)V99 COMP-3 | Credit limit (maintained by CUSTMNT). |
| CBAL | 9P 2 | S9(7)V99 COMP-3 | Customer balance (billed up by BILLPOST). |
Seed: C00001 ACME CORP / A / 5000.00, C00002 BETA LLC / B /
2000.00, C00003 GAMMA INC / A / 1000.00 — all opening balance 0.00.
| Field | DDS type | COBOL PIC | Meaning |
|---|---|---|---|
| INVNO | 6A | X(6) | Invoice number, e.g. I00001. |
| ICUSTID | 6A | X(6) | Owning customer id (matched to CUSTMPF.CUSTID). |
| IAMT | 9P 2 | S9(7)V99 COMP-3 | Gross (pre-discount) invoice amount. |
| ISTAT | 1A | X(1) | Status — O (open) is what BILLPOST/AGERPT select on. |
Seed: I00001 C00001 1000.00 O, I00002 C00002 500.00 O, I00003 C00001 250.00 O,
I00004 C00003 800.00 O. Read via ORGANIZATION IS SEQUENTIAL with
COPY DDS-ALL-FORMATS.
| Field | DDS type | COBOL PIC | Meaning |
|---|---|---|---|
| GLACCT | 6A | X(6) | Account — AR1000 (receivable, debit) or RV2000 (revenue, credit). |
| GLINVNO | 6A | X(6) | Source invoice number. |
| GLAMT | 9P 2 | S9(7)V99 COMP-3 | Signed amount: net debit (+) to AR, net credit (−) to REV. |
Written OPEN EXTEND (append). Two rows per posted invoice; across a run the
signed GLAMT sums to 0.00 — the double-entry invariant BILLPOST maintains.
The application's file list names a RATEPF discount-rate table keyed on customer class.
In the committed reference build the discount logic itself lives in RATELOOK
(class A→10%, B→5%, else 0%, as literals), so the running billing cycle derives its rate from
the customer class through that program rather than by reading a rate row. RATEPF is the
documented place a data-driven rate table would live; the reference estate keeps the rate in code to
demonstrate COBOL-to-COBOL packed-decimal math.
GLPF and CUSTMPF are placed under journal BILLJRN (receiver
BILLRCV) via STRJRNPF before the cycle runs. A billing run therefore lands
8 PT (put/write) entries on GLPF and update entries on CUSTMPF —
the audit/recovery trail the tests assert against.
BAD rather than failing.BILLIB and the seed/updated data is in place
(customers in CUSTMPF, OPEN invoices in INVHPF).STRJRNPF on GLPF and CUSTMPF
under BILLJRN (done once at setup).SBMJOB CMD(CALL PGM(BILLIB/BILLPOST)) (or a bare CALL).CALL BILLIB/AGERPT for the per-customer open-amount report.CALL BILLIB/GLTOTPGM to reconcile the GL row count.CALL BILLIB/CUSTMCL (CL wrapper) or a direct
CALL BILLIB/CUSTMNT PARM(…).Post-checks after BILLPOST:
BILLPOST N=004 BAD=000 (4 invoices posted, no missing customers).QSYSPRT report carries the BILLING RUN REPORT header, one line
per invoice (I00001…I00004), and POSTED=004 BADCUST=000.SUM(GLAMT) = 0.00; 8 PT journal entries on GLPF; ≥3 update
entries on CUSTMPF.Every figure below is a driver-computed oracle asserted against the engine's actual output. The two drivers report 14/14 (billing cycle) and 6/6 (edge probes) — 20/20 total.
| # | Check | Expected |
|---|---|---|
| 1 | RATELOOK direct, class A on 1000.00 | net 900.00 (packed COMP-3) |
| 2 | BILLPOST ran | BILLPOST N=004 BAD=000 |
| 3 | Customer balances (keyed REWRITE) | 1125.00 / 475.00 / 720.00 |
| 4 | GL postings | 8 rows, sum 0.00 |
| 5 | GL writes journaled | 8 PT entries on GLPF |
| 6 | Customer REWRITEs journaled | ≥3 update entries on CUSTMPF |
| 7 | Printer report spooled | header + 4 lines + POSTED=004 BADCUST=000 |
| 8 | CUSTMNT direct update (by-ref) | status 00, balance 475.00 echoed |
| 9 | CUSTMNT REWRITE landed | C00002 limit 2500.00, balance 475.00 untouched |
| 10 | CUSTMCL (CL CALL PARM) delete | status 00 echoed to CL var |
| 11 | DELETE removed the row | C00003 gone; 2 customers remain |
| 12 | Re-DELETE of missing key | FILE STATUS 23 (not silent success) |
| 13 | AGERPT embedded-SQL aggregation | AGE C00001 TOT=1250.00 CNT=2, then AGERPT DONE |
| 14 | CRTCBLMOD+CRTPGM bind (GLTOTPGM) | GLROWS=8 |
| 15 | Probe1a unfiltered ORDRD | 4 rows, total 1370.00 |
| 16 | Probe1b OPNQRYF QRYSLT (NE only) | 2 rows, total 1200.00 |
| 17 | Probe1c after CLOF | reverts to 4 rows, 1370.00 |
| 18 | Probe2 dynamic CALL by identifier | DYNCLR SAW [DYNAMICV] |
| 19 | Probe3 COBOL CANCEL re-init | COUNT 1, 2, then reset to 1 (not silent-wrong 3) |
| 20 | Probe4 negative COMP-3 edited PIC | 1234.56- (trailing minus) |
HAVING COUNT(*) > 1 report — only C00001
(I00001 + I00003 = 1250.00 gross) appears.| Situation | Behaviour | Action |
|---|---|---|
| Missing customer for an invoice | BILLPOST bumps BAD and skips (no post, no GL). | Add the customer to CUSTMPF, re-seed and re-run; the BAD= count flags it. |
| Re-running BILLPOST | Not idempotent — INVHPF stays OPEN, so balances re-grow and GL doubles. | Reset seed data (drop/reload CUSTMPF balances + GLPF) before a re-run. |
| CUSTMNT on a missing key | READ fails; status 23 returned, balance 0. | Non-00 LK-OUTSTAT surfaces to the caller; verify the id and retry. |
| Re-DELETE an already-deleted key | Returns status 23, no error. | Treat 23 as “already gone”; safe. |
| AGERPT SQL error | WHENEVER SQLERROR GO TO SQL-ERR DISPLAYs SQLERR nnn and GOBACKs. | Read the SQLCODE; fix data/schema and re-run (AGERPT is read-only + COMMIT, safe to repeat). |
| GL row count off | GLTOTPGM DISPLAYs GLROWS=n≠expected. | Compare to 2×(posted invoices); investigate a partial BILLPOST run via the journal. |
GLPF and CUSTMPF are journaled to BILLJRN,
a billing run's writes and balance updates are fully reconstructable after the fact for reconciliation
and recovery, even though the app has no maker–checker gate.Each program and the exact ILE-COBOL-on-i feature it demonstrates, grounded in the source members in
cobol-app/test/billing_cycle.mjs and edge_probes.mjs. All objects are in
BILLIB (edge probes in EDGELIB). Compiled with CRTBNDCBL (COBOL),
CRTCLPGM (CL), and the module path CRTCBLMOD+CRTPGM.
LINKAGE/no-file subroutine. Chooses a discount from LK-CLASS
(A→10.00, B→5.00, else 0.00 into WS-DISC PIC S9(3)V99 COMP-3), then
COMPUTE LK-NET = LK-AMT - (LK-AMT * WS-DISC / 100) — all packed
COMP-3. Ends with EXIT PROGRAM (a called *PGM). Demonstrates:
LINKAGE SECTION + PROCEDURE DIVISION USING, COBOL-to-COBOL CALL by reference (BILLPOST calls it),
and packed-decimal arithmetic. Verified: class A on 1000.00 → 900.00.SELECT … ASSIGN TO clauses: DATABASE-INVHPF (SEQUENTIAL),
DATABASE-CUSTMPF (INDEXED, DYNAMIC, RECORD KEY C-ID), DATABASE-GLPF
(SEQUENTIAL, opened EXTEND), and PRINTER-QSYSPRT. The invoice FD uses
COPY DDS-ALL-FORMATS OF INVHPF; the others are hand-coded records. The loop keyed-reads
the customer, CALLs RATELOOK, REWRITEs the balance, WRITEs
two GL rows, and WRITEs report lines with STRING + numeric-edited
WS-ED PIC Z(6)9.99. Demonstrates: keyed and sequential EXTFH I/O in one program,
OPEN EXTEND, printer file I/O, COPY DDS-ALL-FORMATS, FILE STATUS checking,
and calling another *PGM. Every write is journaled to BILLJRN.I-O maintenance over CUSTMPF (DYNAMIC, RECORD KEY C-ID). Reads the requested
customer and dispatches on LK-ACTION: U → REWRITE new limit;
D → DELETE CUSTF RECORD; else inquire. Returns LK-OUTSTAT
(FILE STATUS) and LK-OUTBAL by reference. Demonstrates: LINKAGE SECTION +
PROCEDURE DIVISION USING with mixed char/packed parms passed by reference, and keyed
READ/REWRITE/DELETE. FILE STATUS 23 is returned for a not-found key.DCLs the five parms (*CHAR and *DEC(9 2)),
CALL PGM(BILLIB/CUSTMNT) PARM(…), then SNDPGMMSGs the echoed
STATUS=[nn] BAL=[amt]. Demonstrates: the CL→COBOL CALL PARM
boundary and reading COBOL OUT parms back into CL variables (incl. *DEC↔COMP-3).EXEC SQL INCLUDE SQLCA; WHENEVER SQLERROR GO TO SQL-ERR; a
DECLARE C2 CURSOR FOR SELECT ICUSTID, SUM(IAMT), COUNT(*) … WHERE ISTAT='O' GROUP BY
ICUSTID HAVING COUNT(*) > 1 ORDER BY ICUSTID; then OPEN / FETCH-loop (FETCH C2 INTO
:WS-CUST, :WS-TOT:WS-IND, :WS-CNT, with a null indicator on the sum) / CLOSE / COMMIT.
Demonstrates: embedded SQL in ILE COBOL — cursor, host variables, a null
indicator variable, WHENEVER error branching, and COMMIT. Verified:
only C00001 qualifies (TOT=1250.00, CNT=2).WS-N, built as a
*MODULE (CRTCBLMOD) then bound to a *PGM
(CRTPGM PGM(GLTOTPGM) MODULE(GLTOTMOD)). Demonstrates: the separate
compile-then-bind ILE path (vs. the one-step CRTBNDCBL the other programs use).
Sets RETURN-CODE. Verified: GLROWS=8.ORGANIZATION SEQUENTIAL reader over ORDPF. An OPNQRYF …
QRYSLT('OREG *EQ "NE"') rides the open, restricting the COBOL read to 2 rows (1200.00);
CLOF then reverts it to the full 4 rows (1370.00). Confirms OPNQRYF is snapshot-scoped,
not a stuck or silently-ignored filter.CALL WS-PGM where WS-PGM is an identifier (not a literal) resolves the
target *PGM at run time and the by-ref update is visible: DYNCLR SAW [DYNAMICV].CANCEL "STATEFUL" between calls: the correct ILE semantics re-initialize the
callee's WORKING-STORAGE, so the counter reads 1, 2, then 1 again after CANCEL (a silent no-op
that left it at 3 would be flagged as wrong). Verified reset.COMP-3 (-1234.56) moved through a numeric-edited
PIC Z(6)9.99- shows a trailing minus (1234.56-), not a dropped or garbled
sign.| Feature | Program(s) |
|---|---|
| LINKAGE SECTION + PROCEDURE DIVISION USING | RATELOOK, CUSTMNT, DYNTGT |
| COBOL→*PGM CALL (literal & by identifier) | BILLPOST→RATELOOK; DYNCLR→DYNTGT |
| CL CALL PARM into COBOL | CUSTMCL→CUSTMNT |
| ASSIGN TO DATABASE- keyed (INDEXED/DYNAMIC) I/O | BILLPOST, CUSTMNT |
| ASSIGN TO DATABASE- sequential I/O + OPEN EXTEND | BILLPOST (GLF), GLTOTMOD, ORDRD |
| PRINTER-QSYSPRT report I/O | BILLPOST |
| COPY DDS-ALL-FORMATS | BILLPOST (INVHPF) |
| Packed-decimal (COMP-3) math & edited PICTUREs | RATELOOK, BILLPOST, NEGDISP |
| Embedded EXEC SQL (cursor, indicator, WHENEVER, COMMIT) | AGERPT |
| CRTCBLMOD + CRTPGM bind path | GLTOTMOD/GLTOTPGM |
| OPNQRYF/QRYSLT over a COBOL sequential read; COBOL CANCEL | ORDRD; CANCTEST/STATEFUL |
SELECT clause tying a logical file to an IBM i physical/logical file by name
(e.g. DATABASE-CUSTMPF), so COBOL EXTFH I/O reads/writes the DB file.*PGM.P). All
money fields here are COMP-3; RATELOOK's discount math runs in it.COPY that pulls the externally-described DDS record layout into an FD, so field
names (e.g. INVNO, ISTAT) are usable without hand-coding the record.*MODULE, then bind one or more modules into
a *PGM — contrasted with one-step CRTBNDCBL.READ/WRITE/
REWRITE/DELETE) reaches the IBM i database files.00 success, 23 record not
found. CUSTMNT returns it to its caller as LK-OUTSTAT.:WS-TOT:WS-IND) signalling SQL NULL for the
fetched column.QSYSPRT); BILLPOST writes its run
report there.SBMJOB CMD(CALL PGM(BILLIB/BILLPOST)).