Table Controls in Dynamics AX 2012

by | Updated August 15, 2016 | Development, Dynamics AX

I recently had a request to create a custom form that would be used to enter data into a matrix.  The rows and columns needed to be dynamic as they would be coming from other custom tables. Standard Dynamics AX grid controls don’t really lend themselves do doing this well. The dynamic row and column portion of this also would make building this with a series of text boxes or in a list a challenge.

The dynamic nature of this feature really pointed to the use of a Dynamics AX native control called a table control. Here is a description of the table control from MSDN:

Table in Dynamics AX

The control allows you to control via code the number of rows and columns, so it meets the criteria of being dynamic in sizing. It also allows you to control the type of data that goes into a specific row/column combination (called a cell), so I would have control over what can be edited or not (dynamic header area and data area). The downside is that you have to control all operations (creating the data in the table, saving the data in the table, has the data been edited in any way prior to closing or a save). However, I could not see a better fit for using this control in the feature to get what is desired.

I am going to document how to use the control by specifically calling out code and design pieces of the form. This will allow anyone to examine and trace how this was implemented as a learning process as well.

Step 1.  Add the control

This is standard Dynamics AX functionality. Right click in the area you want to place the control, and choose New control >> Table. Once the control is added open the properties of the control and do the following:

• Give it a meaningful name (for my feature, I chose dataTable as it will be displaying the data to the end user in a Table control).  This is accomplished by changing the Name property.

• Set the AutoDeclaration property to Yes.  This is done as the code will be referenced by name multiple times in X++ code

• Set the Width property to be Column width.  This allows the width to resize if the form size changes.

• Set the Height property to be Column height.  This allows the height of the control to resize if the form size changes.

NOTE: if the table control is a child of a different control (a Group control for example), the parent control Width and Height properties must also be set as above to allow the resize to work as desired.

Step 2. Table control additional components need to be added

This is going to sound a bit strange, but different types of controls need to be added to the table.  The table control will be used to display header information (not editable) and matrix data (editable with a custom lookup).

With a table control, the developer adds the specific type of control to the table one time, sets the desired properties, and then via code returns the type of control needed in a specific cell.  For this feature, I created 2 different controls (both of type StringEdit).  This is done by right clicking on the table, choosing New control >> StringEdit.

The first control is named catLine, and will be used to display the header information for rows and columns. This data will come from tables that were populated via the two prerequisite task for this feature.

The catLine control has the following properties set to control the display and functionality:

• Name: catLine

• AutoDeclaration: Yes

• AllowEdit: No

• BackgroundColor: Tooltip background

The second StringEdit control that is added is called editLine, and has the following properties set:

• Name: editLine

• AutoDeclaration: Yes

• BackgroundColor: Highlight text

The rest of the properties for both controls are left as the defaults.

Step 3. Control what type of control displays in a cell in the table

The table control method editControl() needs to be overridden/created to control what type of control is displayed in a specific cell of the table.  The requirement I used what the first two rows of the table control would be used for the customer group information, and the first two columns of the table control would contain the product group information.  This would be displayed using the catLine control.  The rest of the table would be editable, thus requiring the use of the editLine control.

The method will return an object of type FormControl, and takes in two parameters.  The first parameter is the column of the table, and the second is the row of the column.

Here is the X++ code that implements the above requirements:


At this point, if you were to implement the above, and open the form, you would see a table control that looks like the following:

Blank Table

The yellowish cells are not editable (column labels and row labels) while the white cells are where the matrix data would be entered.

Step 4. Populate an empty table

The next step is to use the information to populate an empty table control so the matrix data can be created. This was done in a custom method named buildNewMatrix(). This method retrieves data from the two different tables (customer and product group), and builds an empty matrix in the table control. Data is populated on a cell by cell basis in the table control.

This is the method code:


NOTE: notice the comments for BP Deviation documented.   When working with the data in this manner, the form doesn’t really enforce security as the data is retrieved by code.  This is why the comments are in the code (otherwise best practice violations are thrown).  The line:

is used to make sure security is enforced at the table level when the data is retrieved. 

Also notice how the cell locations are controlled when building out the table.  Hard coded values can be used to populate specific cells, and variables are used to control how the columns are populated.

Step 5. Reading or writing data with the table control

After the data entry has been completed, OR if you want to load additional information into the table control, the same technique can be used. Data is accessed via the cell, retrieved, set to a field in a table buffer, and written to the table. This all has to be done via code (as stated previously) since the form does not have a datasource.

The method saveNewMatrix demonstrates how to save the data to a table.

// REMEMBER that the cell location is referenced as COLUMN,ROW in the cell method
Row         startRow = 3;
Row         endRow = dataTable.rows();
Row         cellRow;

Column      startColumn = 3;
Column      endColumn = dataTable.columns();
Column      cellCol;


Step 6. Dealing with ‘dirty’ data and other control features

The term ‘dirty’ data means the data has been modified, and not yet saved. On normal forms, this is taken care of for the user automatically. In this instance, the Developer is going to have to be aware of the state of the data.  This really is not that difficult to accomplish though. Remember that the table control only has 2 different controls on it, and one of them is read only.  This means that by modifying the modified() method of the CONTROL, we can determine if ANY of the data in the table control has been changed.

Here is the modified method of the editLine control (the changedMatrix variable is a boolean that is declared in the classDeclaration of the form):

One requirement was to have a lookup for the data in the matrix as well.  Again, as this is only a single control for data entry, the lookup() method of this control can be modified to provide the desired functionality throughout the data entry portion of the table control.

The above information should provide enough understanding of a seldom used control that exists within Dynamics AX. A Developer can really use this control for a number of purposes, and by adding many different types of controls to the table, have diverse functionality on a form.

I have attached an xpo file that contains a simple form that quickly demonstrates some of these concepts as well.

Xpo File


Related Posts

  • The Safari browser is now supported natively on Dynamics AX 2012 R2 as well as being supported on Dynamics AX RTM with a hotfix.  Taken from the updated System Requirements…

  • I put together some certification information on the requirements for Microsoft Dynamics AX 2012 and a proposed training roadmap to get to each of the core certifications.  Rather than have this…

  • With the announcement of the release of Microsoft Dynamics AX 2012 R2, Microsoft released an updated system requirements document for AX 2012:  Windows 2012 Server is now supported, but…



  1. Table Controls in Dynamics AX 2012 – 9/28, Stoneridge Software | - […] Continue reading on Source Blog […]

Submit a Comment

Your email address will not be published. Required fields are marked *

Upcoming Events


07oct12:00 pm1:00 pmThe Three Paths to Business Central from Dynamics GP

08oct11:00 am12:00 pmConfab with Stoneridge - Livestream - The Vision and Strategy of Microsoft Business Systems

14oct10:00 am10:30 amThe Modern Manufacturer - Managing Complex Cost Modeling

14oct12:00 pm12:30 pmGenerating Custom Inspection or Process Forms

19octAll Day22Stoneridge Connect Fall 2020

22oct11:00 am12:00 pmConfab with Stoneridge - Livestream - Stoneridge Connect Recap

28oct10:00 am10:30 amThe Modern Manufacturer - Engineering Change Management: Introduction of NEW Functionality for Manufacturers Using Dynamics 365


18nov10:00 am10:30 amThe Modern Manufacturer - Tears and Trauma of MRP

About Stoneridge
Stoneridge Software is a unique Microsoft Gold Partner, with emphasis on partner. With specialties in Microsoft Dynamics 365, Microsoft Dynamics AX, Microsoft Dynamics NAV, Microsoft Dynamics GP and Microsoft Dynamics CRM, we focus on attracting the most knowledgeable experts in the field to our team, and prioritize delivering stellar solutions with maximum impact for your business. At Stoneridge, we are deeply committed to your results. Each engagement is met with a dedicated team, ready to provide thorough, tailored, and expert service. Based in Minnesota, we intentionally “step into your shoes,” wherever you are. We focus on what you care about, and develop trusting, long-term relationships with our clients.

Subscribe To Our Blog

Sign up to get periodic updates on the latest posts.

Thank you for subscribing!