Half the polish in a good Acumatica document layout is things not printing: the "CREDIT MEMO" banner that only appears on credit memos, the discount column that vanishes when no line has a discount, the second address block suppressed when billing and shipping match. All of this is conditional visibility, and the Report Designer gives you three distinct mechanisms for it — VisibleExpr on controls, visibility on whole sections, and conditional styles. Knowing which one to use where is most of the craft.
VisibleExpr on controls
Every control — TextBox, PictureBox, Line, Panel — has a VisibleExpr property that takes an expression returning true or false. The expression language is the same one used everywhere in the designer: fields in square brackets, parameters with @, VB-flavoured functions.
-- show a PAID stamp only when balance is zero on a released doc
=[ARInvoice.Released] = True And [ARInvoice.CuryDocBal] = 0
-- print the discount column only when the parameter asks for it
=[@ShowDiscounts] = True
-- suppress a label when the field is empty
=IsNull([SOOrder.CustomerOrderNbr], '') <> ''
-- credit memo banner
=[ARInvoice.DocType] = 'CRM'
Two habits that save debugging time. First, be explicit about null: [Field] <> '' is false-ish when the field is null in ways that surprise people, so wrap with IsNull(...). Second, remember string comparisons against DAC values use the stored value, not the UI label — a document type is 'CRM', not 'Credit Memo'. Check the DAC's list attribute values when in doubt.
Hidden is not collapsed: the whitespace problem
Setting a control invisible leaves its space behind — you get a gap where the discount column was. Whether that is acceptable depends on the layout:
- For stacked blocks (address lines, remittance advice), put the controls in their own section and hide the section. A hidden section collapses vertically; hidden controls inside a visible section do not.
- For columns, the band model has no reflow — hiding a column's TextBoxes leaves a blank stripe. If a column must truly come and go, the honest options are two report variants, or laying out the "optional" column at the right edge where its absence reads as margin rather than a hole.
- For single lines within a block, a one-line section per optional line is heavy-handed but works; I use it for things like "VAT Exemption Reason" that print on maybe 5% of invoices.
Section-level visibility and group tricks
Sections (page header, group headers/footers, details) accept a VisibleExpr too, and this is where the structural conditional logic lives. Patterns I use constantly:
- Suppress an empty group. Group footer with
=Count([SOLine.LineNbr]) > 0— though usually the better fix is filtering the rows in the schema. - First-page-only blocks. Terms and conditions on page one only:
=[PageOf] = 1style expressions vary by build; the reliable pattern is a group on a constant with its header's Print On behaviour set appropriately, or placing the block in the report header rather than the page header. - Different layouts per document type. One report serving invoices and credit memos: duplicate the sensitive sections, give each a
VisibleExpronDocType. Past two variants this becomes unmaintainable — split into two.rpxfiles and point the workflow's print actions at each.
A control hidden by expression is still populated from the dataset, and the value still exists in the rendered file's data in some export formats. Never use VisibleExpr to hide cost or margin from a class of users — that is a job for separate reports guarded by access rights, or for removing the field from the schema entirely.
Conditional formatting via style expressions
Often the requirement is not hide/show but emphasise: overdue balances in red, negative quantities bolded. Controls expose style properties as expressions — ForeColor, Font.Bold and friends can be driven by data:
ForeColor: =IIf([ARInvoice.DocDate] < [@AsOfDate] And [ARInvoice.CuryDocBal] > 0,
'Red', 'Black')
Font.Bold: =IIf([SOLine.OrderQty] < 0, True, False)
Keep these boring. Reports print on monochrome laser printers more often than designers expect; pair colour with a text cue (an asterisk, "OVERDUE") so the information survives greyscale.
Testing the matrix
Conditional visibility multiplies your test cases: document type × paid state × parameter flags. My routine before shipping a document layout is a small grid of real documents — a standard invoice, a credit memo, a zero-balance invoice, one with every optional field empty, one with all of them populated — printed to PDF and eyeballed side by side. It takes twenty minutes and it has caught an embarrassing "PAID" stamp on an open invoice (null balance treated as zero — the IsNull habit again) before the client did.
Wrapping up
Use VisibleExpr on controls for stamps and labels, section visibility for anything that must collapse, and style expressions when the answer is emphasis rather than absence. Handle nulls explicitly, compare against stored values not labels, split the report when type-based variants exceed two, and never mistake visibility for security. The result is one layout that quietly does the right thing on every document type — which is exactly what nobody will ever compliment you on, because good conditional visibility is invisible.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.