One of the first major projects I took on in AX was creating a report from scratch. I didn’t know really anything about what to do or where to start. I did some research and found some posts about using a RDP (Report Data Provider) Class so I walked through the steps. I ran into some issues but eventually worked through them all. This was the real reason I decided to start a blog. I was so happy there was info out there showing me how to do this so I want to give back. I know I’m creating something that already exists out there but the more options for people to use as examples, the better I say.
For my example, I was creating a Machine Order Confirmation (MOC) report that users could create from a Sales Quotation in the SalesQuotationListPage. The VERY FIRST thing I do is figure out the query to get the information you want. I use SSMS (SQL Server Management Studio) to so that. I’m not going to show that here, but I have another blog about that. For now, let’s say you know how you are going to get your information. For this example, my query is selecting records from SalesQuotationTable and joining a bunch of other tables. My main “where” clause is where SalesQuotationTable.QuotationID is equal to something. This will come up later but it’s important to know where this is coming from.
Once you have your query ready then let’s follow these steps to get a working report using Contoller/Contract/RDP Classes:
- Create a new table by right-clicking Tables and choosing New-Table.
- Set the TableType as InMemory.
- Drag and drop the fields you want to display from the tables you are querying into your temp table. This is why it’s good to know where you are getting the info from. You can always add it later but it’s obviously better/easier to know ahead of time.
- Create a new class by right-clicking Classes and choosing New-Class. This will be your Contract Class.
- Name it something appropriate. For my example I named it SalesMOCController. Note that I’m getting QuotationID because of my “where” clause in my query. Here is the code:
public class SalesMOCContract
public QuotationId parmQuotationID(QuotationId _quotationId = quotationId)
quotationId = _quotationId;
- Create another class for your Controller Class and name it appropriately. Mine is called SalesMOCController. Note that the line where salesQuotationTable = args.record(); is where you are getting your main info from in your query. I also needed to prompt for QuotationID so I can pass it into the report. See above if you are confused. Lastly, there is a line in there that points to the report. My report is called SalesMOC with a design called Report. More about that later. Here is the code:
class SalesMOCController extends SrsReportRunController
protected void prePromptModifyContract()
SalesQuotationTable salesQuotationTable;contract = this.parmReportContract().parmRdpContract() as SalesMOCContract;salesQuotationTable = args.record();contract.parmQuotationID(salesQuotationTable.QuotationId);
public static client void main(Args args)
SalesMOCController controller = new SalesMOCController();controller.parmArgs(args);
- Create one more class for your RDP Class. I called mine SalesMOCDP. Here is the code:
class SalesMOCDP extends SRSReportDataProviderBase
InventTable inventTable;QuotationId quotationid;
public SalesMOCTmp getSalesMOC()
select * from salesMOCTmp;
private void insertIntoSalesMOCTmp()
InventDim inventDim;contract = this.parmDataContract() as SalesMOCContract;
quotationid = contract.parmQuotationID();while select salesQuotationLine
order by configChoice.chosengroupid
where salesQuotationLine.QuotationId == quotationid
where inventDim.inventDimId == salesQuotationLine.InventDimId
where configChoice.ConfigId == inventDim.configId
where configGroup.ConfigGroupId == configChoice.ChosenGroupId
where bom.BOMId == salesQuotationLine.ItemBOMId
&& bom.ConfigGroupId == configChoice.ChosenGroupId
where inventTable.ItemId == bom.ItemId
salesMOCTmp.QuotationId = salesQuotationLine.QuotationId;
salesMOCTmp.ItemId1 = bom.ItemId;
salesMOCTmp.ChosenItemId = configChoice.ChosenItemId;
salesMOCTmp.NameAlias = inventTable.NameAlias;
salesMOCTmp.ChosenGroupId = configChoice.ChosenGroupId;
salesMOCTmp.Name = configGroup.Name;
salesMOCTmp.Mandatory = configGroup.Mandatory;
salesMOCTmp.MultipleOptions = configGroup.MultipleOptions;
/// Processes the SQL Server Reporting Services report business logic
/// This method provides the ability to write the report business logic. This method will be called by
/// SSRS at runtime. The method should compute data and populate the data tables that will be returned
/// to SSRS.
public void processReport()
- When you compile, you will get errors, mainly because you haven’t created the report yet so let’s do that. Open Microsoft Visual Studio (I have 2010 professional).
- Click File-New-Project.
- Choose Report Model, name the project something appropriate (I named mine SalesMOC) and then click OK.
- Right-click on the Project in the Solution Explorer and choose Add-Report.
- Rename the report. Mine is SalesMOC.
- Right-click on Datasets and choose Add Dataset.
- Rename the dataset and change the Data Source Type to Report Data Provider. Then click the ellipsis in the Query box.
- Find the Data Provider Class you created, highlight it and choose Next.
- Choose the fields you want in your report. You don’t have to display them all so feel free to choose them all.
- Right-click Designs and choose Add-Precision Design.
- Rename the design (mine is Report) and change the Style Template to TableStyleTemplate.
- Right-click on the design and choose Edit Using Designer.
- Right-click on the blank form and choose Insert-Table.
- Click on a cell in the tablix so you see the outer rim. Then right-click in the box in the top left corner and choose Tablix Properties.
- Change the Dataset Name to your dataset and click OK.
- Now you can click on the little icon in the cell to bring up a list of fields in your dataset and choose which one you want to show.
- Make table and report look how you want. I’m not going to get into details about that right now, but perhaps I’ll blog about that another day. Save it all then right-click on the Project and choose Deploy. This will push it into AX.
- Now back in your project in AOT, you need to create an Output Menu Item. I called mine SalesMOC. I know, didn’t see that one coming! Point that Output Menu Item to your Controller Class you created earlier.
- Now you create a button on the form that you want to call this report from. I created one on SalesQuotationListPage called CreateMOC. Change the Text in the properties box to what you want the user to see at the button. Point the menu item to the Output Menu Item you just created.
- Go into AX, click the button you just created, and you should see a prompt where you want to send the report.
- You will probably see a text box asking for, in my case, the quotation ID but I have hidden that. To do that go back into your report under parameters and find the one that is being prompted for. Click on it and in the properties, change Allow Blank to True and Visible to Hidden.
- I think that’s it! Please email me if I missed something or it’s not working.