Lines for multiple headers

The goal of today’s excercise is to create a form with two grids (containing headers and corresponding lines). The trick is that if you select multiple headers, the form will display lines for all of them.

The following form uses sales orders. Notice that selected orders are 1, 3 and 4 and displayed lines also belong to orders 1, 3 and 4:

Form

I’ve created two implementations: one for AX2012 and another for AX2009. They’re slightly different – I’m going to describe AX2012 first and then to mention changes done for AX2009. You can find a download link for both at the end.

The form has two data sources (SalesTable and SalesLine), which are not linked together. Filtering and query execution are not handled by AX; they’re explicitly triggered from selectionChanged() method on SalesTable data source.

For each selected header, a new range is added to SalesLine data source:

Ranges

You could use just a single range and create one long value by concatenating order IDs together, separated by space (e.g. “000001, 000002”), nevertheless it has a huge problem: the supported length of range value isn’t unlimited (I even managed to shoot down AX2012 client by using a sufficiently long value). Having several shorter values is also beneficial when displaying ranges in a grid (as in the previous picture).

The implementation itself is very straightforward; you shouldn’t have any problems to understand what’s going on:

public class FormRun extends ObjectRun
{
    MultiSelectionHelper headerSelection;
    QueryBuildDataSource lineQueryDs;
}
 
public void init()
{
    super();
 
    // Initialize MultiSelectionHelper for later use
    headerSelection = MultiSelectionHelper::construct();
    headerSelection.parmDatasource(salesTable_ds);
 
    // For convenient access to lines' QueryBuildDataSource
    // (in AX2012, you could use salesLine_ds.queryBuildDataSource())
    lineQueryDs = salesLine_ds.query().dataSourceNo(1);
}
 
public void selectionChanged() // SalesTable datasource
{
    super();
    SalesLine_ds.executeQuery();
}
 
public void executeQuery() // SalesLine datasource
{
    lineQueryDs.clearRanges();
    this.filterBySelectedHeaders();
 
    super();
}
 
void filterBySelectedHeaders() // SalesLine datasource
{
    SalesTable st = headerSelection.getFirst();
 
    while (st.RecId)
    {
        // Add one range for each selected SalesId
        lineQueryDs.addRange(fieldNum(SalesLine, SalesId)).value(queryValue(st.SalesId));
        st = headerSelection.getNext();
    }
}

In AX2009, we don’t have selectionChanged() method, therefore I combined markChanged() method and a delayed link between data sources, which calls lines’ executeQuery() on header selection. I just had to remove the dynamic link, otherwise AX would show lines for just a single header.

You can download both versions here: LinesForMultipleHeaders.zip.

3 Comments

  1. This seems very difficult to achieve but you approach made is as simple as anything. Very useful and simple to understand.

    Thanks For the Post.

Comments are closed.