How to reuse PurchSelectLines to select a PO line and copy it into an existing Purchase Order (custom form
03:36 09 Feb 2026

I am implementing a feature in D365FO where I want to reuse the standard PurchSelectLines dialog to allow a user to select one or more purchase order lines, and then copy the selected lines into an existing purchase order, just like in standard form VendEditInvoice.

The target purchase order already exists and is displayed in a custom form (CancelDebitNoteDiffs), which has both a header table and a line table.

My goal is:

  • Open the standard PurchSelectLines dialog

  • Let the user select PO lines

  • Copy or add those selected lines into the existing PO shown on my custom form

  • Persist the copied lines into my custom line table

Scenario

  • Custom form: CancelDebitNoteDiffs

  • Header table: CancelDebitNoteDiffsTable

  • Line table: CancelDebitNoteDiffsLine

  • Goal: Select PO lines using standard PurchSelectLines and copy them into the custom line table for an already existing header record.

    1. Button on custom form (Action Menu Item)

public void clicked()
{
    super();

    FormRun                  purchSelectLinesFormRun;
    Args                     args;

    purchFormLetter purchFormLetter = PurchFormLetter::construct(DocumentStatus::Invoice);

    args = new Args();
    args.name(formStr(PurchSelectLines));
    args.record(invoiceInfoTable);
    args.parmObject(purchFormLetter);
    args.caller(element);

    purchSelectLinesFormRun = classFactory.formRunClass(args);
    purchSelectLinesFormRun.init();
    purchSelectLinesFormRun.run();

    // Wait for the form to close (modal)
    purchSelectLinesFormRun.wait(true);
    element.refreshForm(); 
}

2. Handle selected lines returned from PurchSelectLines

public void selectedLines(Common _record)
{
    PurchLine purchLine;
    CancelDebitNoteDiffsTable header;
    CancelDebitNoteDiffsLine line;

    // Current header record on the form
    header = CancelDebitNoteDiffsTable_ds.cursor();

    if (!header)
    {
        warning("No header record selected.");
        return;
    }

    purchLine = _record as PurchLine;

    if (!purchLine)
    {
        return;
    }

    ttsbegin;

    line.clear();
    line.initValue();

    line.CancelDebitNoteId = header.CancelDebitNoteId;
    line.PurchId           = purchLine.PurchId;
    line.LineNum           = purchLine.LineNumber;
    line.ItemId            = purchLine.ItemId;
    line.Qty               = purchLine.QtyOrdered;
    line.PurchPrice        = purchLine.PurchPrice;
    line.LineAmount        = purchLine.LineAmount;
    line.InventDimId       = purchLine.InventDimId;

    line.insert();

    ttscommit;
}

3. Result

  • Standard PurchSelectLines dialog opens

  • User selects one or more PO lines

  • Each selected PurchLine is passed back to the custom form

  • Lines are copied into CancelDebitNoteDiffsLine

  • Existing header remains unchanged

microsoft-dynamics x++ dynamic365