SSRS Report Parameter Order in Dynamics 365

 In Dynamics 365, Dynamics AX

According to Microsoft’s documentation, the order for the parameters in the dialog box when running a report is defined by the order in the rdl (report file) that is constructed through the designer in Visual Studio.

The ordering problem

Our tests show that this is not the case.
The order for the parameters is a two steps order:
First, the parameters are grouped by type. For instance: one group has the data provider parameters (related to its data contract parameters) and other group contains the rdl parameters.
Then the rdl parameters are shown in alphabetical order (not rdl order) and then the data provider parameters are shown also in alphabetical order.

How to change the order?

To make sure that the order is the expected one we have to modify the report controller class and use some helper classes for data contract manipulation.
The orthodox way to do it would be overriding the prePromptModifyContract method in the controller class. The same can be done in the main method before the startOperation() call (that is the way shown in the example).

class MyReportController extends SrsReportRunController
{
    public static void main(Args _args)
    {
        const str designName = 'MyReport.MyPrecisionDesign';
        
        // My parameters (enumerated in the desired order for the dialog box)
        const container rdlParmNames = [
                                         'customer',
                                         'year',
                                         'month',
                                         'invoiceFilter'
                                        ];

        MyReportController controller = new MyReportController();
        
        controller.parmArgs(_args);

        controller.parmReportName(designName);
        
        // Here begins the fun.
        // The report will have 3 contracts. 1 for the data provider, 1 for the rdl and 1 to contain the first two
        SrsReportDataContract contract = controller.parmReportContract();  // Get the "container" data contract
        SrsReportRdlDataContract rdlContract = contract.parmRdlContract(); // Get the rdl data contract (where our params are)
        // We don't care about the data provider contract in this example.

        for (int i=1; i<=conlen(rdlParmNames); i++)
        {
            str parName = conPeek(rdlParmNames, i);

            if (rdlContract.parameterExists(parName)) // Make sure the param name from the container is correct
            {
                // Get the parameter
                SRSReportParameter parameter = rdlContract.getParameter(parName);
                
                // Give order to the parameter. The ordering seems numerical, but it is alphabetical,
                // so the example adds 10 to the loop counter to avoid problems like 1,10,11,2,3
                // This will let us use params from 1 to 89, which should be enough.
                parameter.displayOrderKey(int2Str(i+10)); 
            }
        }
        controller.startOperation();
    }
}
Recent Posts