Řádky pro více hlaviček

Cílem dnešního cvičení je vytvoření formuláře s dvěma gridy (obsahující hlavičky a odpovídající řádky). Trik je v tom, že pokud vyberete více hlaviček, formulář zobrazí řádky pro všechny.

Následující formulář využívá prodejní objednávky. Všimněte si, že vybrané objednávky mají čísla 1, 3 a 4 a zobrazené řádky také patří k objednávkám 1, 3 a 4:

Form

Vytvořil jsem dvě implementace: jednu pro AX2012 a jednu pro AX2009. Nejsou úplně stejné – nejprve popíšu AX2012 a pak zmíním změny nutné pro AX2009. Link na stažení obou verzí najdete na konci.

Formulář má dva datové zdroje (SalesTable a SalesLine), které spolu nejsou spojeny. Fitrování a spouštění dotazu nezajišťuje AX, je spouštěno explicitně z metody selectionChanged() na datovém zdroji SalesTable.

Pro každou zvolenou hlavičku je přidán nový filtr do datového zdroje SalesLine:

Ranges

Mohli byste použít jen jeden filtr a vytvořit jednu dlouhou hodnotu spojením čísel objednávek oddělených čárkou (např. “000001, 000002”), nicméně to má jeden velký problém: podporovaná délka hodnoty filtru není neomezená (použitím dostatečně dlouhé hodnoty se mi dokonce podařilo sestřelit klienta AX2012). Mít více krátkých hodnot je také výhodné při zobrazování fitrů v gridu (jako na předchozím obrázku).

Implementace je docela přímočará, neměli byste v ní jinak tápat:

public class FormRun extends ObjectRun
{
    MultiSelectionHelper headerSelection;
    QueryBuildDataSource lineQueryDs;
}
 
public void init()
{
    super();
 
    // Initalizuj MultiSelectionHelper pro pozdější použití
    headerSelection = MultiSelectionHelper::construct();
    headerSelection.parmDatasource(salesTable_ds);
 
    // Pro pohodlný přístup k instanci QueryBuildDataSource pro řádky
    // (v AX2012 byste mohli použít salesLine_ds.queryBuildDataSource())
    lineQueryDs = salesLine_ds.query().dataSourceNo(1);
}
 
public void selectionChanged() // Datový zdroj SalesTable
{
    super();
    SalesLine_ds.executeQuery();
}
 
public void executeQuery() // Datový zdroj SalesLine
{
    lineQueryDs.clearRanges();
    this.filterBySelectedHeaders();
 
    super();
}
 
void filterBySelectedHeaders() // Datový zdroj SalesLine
{
    SalesTable st = headerSelection.getFirst();
 
    while (st.RecId)
    {
        // Přidej jeden filtr pro každé vybrané SalesId
        lineQueryDs.addRange(fieldNum(SalesLine, SalesId)).value(queryValue(st.SalesId));
        st = headerSelection.getNext();
    }
}

V AX2009 nemáme metodu selectionChanged(), takže jsem zkombinoval metodu markChanged() a “delayed link” mezi datovými zdroji, který při změně hlavičky volá executeQuery() pro řádky. Jen jsem musel odebrat dynamický odkaz (dynamic link), jinak by AX ukázala řádky jen pro jednu hlavičku.

Obě verze můžete stáhnout zde: LinesForMultipleHeaders.zip.