This completes our series. Let’s have some fun with the code. Note: I had to break this post into two different parts to get it to work. What we are doing here is programmatically taking values from a control and altering the data shown based on that selection. Part A can be found here:
Tutorial: Understanding the Simple List & Details form within Dynamics AX 2012R2 Part 5A
Okay, so what if we wanted to actually change the query to take that controls input.
- We need to add a variable that will remain valid for as long as the form is running and can be used in any method. We do that by declaring variables in the class declaration method.
- We need to add that variable, which will be a filter, to the executequery method since that is where we hard change a data source
Make sure that DemoListDetail form is expanded.
Enter in one line of code. Make it look like this. What you are doing here is making the queryfilter variable available to every method in the form. Note, you cannot initialize variables in a class declaration in Dynamics AX. This must be done through methods, which is why we have a special method for turning those variables into actual object – called “init” though any method can initialize variables. We use “init” because it fires first.
Expand Data Sources àCustTable and find methods. Now, we need to add something extra to that data source, so right-click on Methods and choose Override method à init. Remember, we use the init method to initialize variables. We can’t use those variables until they have been initialized in a method.
Now, here we are going to type in code which does this. It will create a variable called QueryFilter. By convention, a datasource is always referred to with the datasource name and an underscore “ds”. We use the word “query” to actually refer to the data access code that gets data. We use the addQueryFilter to specify the equivalent of adding an “AND” to a where clause. In this case the other “And” on the where clause is for the column “Blocked” of CustTable. So, alter the form query to restrict values show in the grid where the column “blocked” value equals some value that we will set in just a moment (hint: it will be the combobox). Last thing over here is notice that there is a field2str conversion. The column is stored as an enum, which is an actual type that returns an integer. This argument requires a string type that is a field name. Using the Field2Str conversion tells the compiler to treat the field name like a string so that it doesn’t get confused on what it is dealing with. This is very common when dealing with columns of types other than string. Notice the call to “super“. “super” says run the original method logic. You add logic above or below super to essentially add code to the original method. It saves you a ton of time because you don’t have to recode everything.
- But the business of data access is always handled in executeQuery for a method. If you don’t see your executeQuery method under the CustTable data source(Expand Data Source --> CustTable. Right-click on Methods and select Overrride Method. Select the ExecuteQuery for overloading.) While we have declared and initialized a method, we actually run our altered query in executeQuery. Thus, we must add our initialized object, “queryFilter” , in here. This code adds a queryfilter before super(where we actually execute our data query for retrieving information). QueryValue is a built in Global Functions. Global functions are little one word methods that you call usually with a parenthesis around whatever they are acting on. In the case of QueryValue, it guarantees that the selected value in DemoComboBox can be parsed and formatted as part of a data retrieval statement. If it can’t, the compiler won’t allow the statement to proceed. As you can guess, it is a best practice to use QueryValue when retrieving values from fields which will affect data retrieval operations. It then looks up the control name and converts the value to a string. The string value is saved in the queryfilter object. Once the queryfilter object is populated, it will then be used in the regular method execution when super() runs.
And, we are all finished!!!
The following table of Form Events was taken from the table below. However, because it is THAT important, I include it in the link below.