Use the Page Management codeunit instead of invoking Page.Run directly

Properties
AC0006 Warning Design Code Fix Ignore Obsolete

When you call Page.Run(Page::"Sales Order", SalesHeader), you hardcode which page opens for a given record. If the record’s "Document Type" is Quote rather than Order, the wrong page opens. The caller is responsible for resolving the correct page variant, and every call site duplicates that logic.

The Page Management codeunit centralizes this resolution. It inspects the record, determines the correct card or list page — including document-type variants like Sales Order vs. Sales Quote — and opens it. It also checks IsGuiAllowed() before running the page, converts record variables to RecordRef automatically, and publishes the OnAfterGetPageID event so other extensions can override page selection without modifying existing code.

Example

The following code hardcodes the page for a Sales Header record:

procedure ShowSalesDocument()
var
    SalesHeader: Record "Sales Header"
begin
    Page.Run(Page::"Sales Order", SalesHeader); // Use the Page Management codeunit instead of invoking Page.Run directly [AC0006]
end

This opens the Sales Order page regardless of the document type. If SalesHeader is a Quote, the user sees the wrong page.

To fix this, use the Page Management codeunit:

procedure ShowSalesDocument()
var
    SalesHeader: Record "Sales Header"
    PageManagement: Codeunit "Page Management";
begin
    PageManagement.PageRun(SalesHeader);
end;

PageManagement.PageRun() resolves the correct page — Sales Order, Sales Quote, Sales Invoice, or Sales Credit Memo — based on the record’s "Document Type" field.

Card vs List pages

Page Management is intended for card pages and worksheet pages (journals). For list pages, use GetDefaultLookupPageIDByVar() to resolve the page ID from the table’s LookupPageId property:

procedure ShowSalesHeaders(var SalesHeader: Record "Sales Header")
var
    PageManagement: Codeunit "Page Management";
begin
    if SalesHeader.Count() = 1 then
        PageManagement.PageRun(SalesHeader)
    else
        Page.Run(PageManagement.GetDefaultLookupPageIDByVar(SalesHeader), SalesHeader);
end;

When the diagnostic is reported

The diagnostic triggers on Page.Run() or Page.RunModal() calls that pass a record of a supported table type. The diagnostic also triggers when Page.Run(0, Record) is used — passing 0 as the page ID defers to the table’s default page, but Page Management provides the same resolution with additional logic and extensibility.

The following tables are supported:

IdName
36Sales Header
38Purchase Header
79Company Information
80Gen. Journal Template
81Gen. Journal Line
91User Setup
98General Ledger Setup
112Sales Invoice Header
131Incoming Documents Setup
207Res. Journal Line
210Job Journal Line
232Gen. Journal Batch
312Purchases & Payables Setup
454Approval Entry
843Cash Flow Setup
1251Text-to-Account Mapping
1275Doc. Exch. Service Setup
5107Sales Header Archive
5109Purchase Header Archive
5200Employee
5405Production Order
5900Service Header
5965Service Contract Header
7152Item Analysis View
2000000120User

Exception

The diagnostic is not raised in the following cases:

  • No record context: Page.Run(Page::"Customer Card") without a record parameter. Page Management resolves pages from a record — when there is no record, Page.Run is the correct approach.

  • Capturing the return action: when Page.RunModal() returns an Action value that is used in a condition. Page Management methods return Boolean, not Action, so this pattern requires the direct call:

procedure SelectCustomer()
var
    Customer: Record Customer;
begin
    if Page.RunModal(Page::"Customer Lookup", Customer) = Action::LookupOK then
        ProcessSelectedCustomer(Customer);
end;
  • Page declared as a variable: when you declare the page as a variable and call SetRecord() then Run(), the page type is already determined at declaration. This pattern is used when you need to call methods on the page instance before running it:
procedure ShowCustomer(var Customer: Record Customer)
var
    CustomerCard: Page "Customer Card";
begin
    CustomerCard.SetRecord(Customer);
    CustomerCard.Run();
end;
  • Temporary records: Page Management skips temporary records because page resolution is based on table metadata that does not apply to temporary data.

Code fix

The code fix replaces Page.Run and Page.RunModal calls with the corresponding Page Management method:

  • Page.Run(Page::X, Record) becomes PageManagement.PageRun(Record).
  • Page.RunModal(Page::X, Record) becomes PageManagement.PageRunModal(Record).
  • When a field parameter is present, Page.Run(Page::X, Record, FieldNo) becomes PageManagement.PageRunAtField(Record, FieldNo, false) and the modal variant uses true for the third parameter.

See also