0% found this document useful (0 votes)
366 views172 pages

Reference Companion Guide 80730

Uploaded by

tarek abib
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
366 views172 pages

Reference Companion Guide 80730

Uploaded by

tarek abib
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 172

Reference Companion Guide

Course 80730 Development Basics in


Microsoft Dynamics AX
The Reference Companion Guide is a Students guide and take away for this course. Please download, email or
upload this guide for future use and take notes or provide additional information on any given topic.

The Reference Companion Guide should be used in conjunction with an E-Learning or trainer led instruction
course.
____________________________________________________________________________________________________________________
NOTE:
Module practices and demonstrations in this course are performed on prerelease version of Microsoft Dynamics
AX (Version AX7 CTP7).
All practices should be performed in the same sequence as the course, as they are interdependent.
____________________________________________________________________________________________________________________

CONTENTS
Module 0: Fleet Management Case Study........................................................................................................................................... 7
Module 1: Introduction to Visual Studio.............................................................................................................................................. 7
Lesson 1: Module Overview..................................................................................................................................................7
Lesson 2: Fleet Management Scenario..................................................................................................................................7
Lesson 3: Setup and Configuration........................................................................................................................................7
Lesson 4: Terminology and Concepts....................................................................................................................................8
Lesson 5: Naming Convention...............................................................................................................................................8
Lesson 6: Navigation.............................................................................................................................................................8
Lesson 7: Projects, Models, and Packages...........................................................................................................................10
Lesson 8: Using Elements....................................................................................................................................................12
Lesson 9: Performing Builds................................................................................................................................................13
Module Review............................................................................................................................................................................................ 14
MODULE 1 KEY TAKE AWAY..................................................................................................................................................................... 14
MODULE P RACTICE....................................................................................................................................................................................... 15
Practice 1.1: Configure Visual Studio................................................................................................................................................... 15
Practice 1.2: Create a Project.................................................................................................................................................................. 16
Practice 1.3: Create an Element............................................................................................................................................................. 17
Practice 1.4: Build and Compile............................................................................................................................................................. 18
Module 2: Architecture............................................................................................................................................................................. 20
Lesson 1: Application Stack.................................................................................................................................................20
Lesson 2: Server Architecture..............................................................................................................................................20
Lesson 3: Cloud Architecture...............................................................................................................................................21
Module Review............................................................................................................................................................................................ 21
MODULE 2 KEY TAKE AWAY ..................................................................................................................................................................... 21
Module 3: Labels and Resources........................................................................................................................................................... 24
Lesson 1: Labels................................................................................................................................................................... 24
Lesson 2: Fleet Management Scenario................................................................................................................................24
Lesson 3: Create and Use Labels.........................................................................................................................................24
Lesson 4: Search Labels.......................................................................................................................................................25
Lesson 5: Best Practices for Labels......................................................................................................................................25
Lesson 6: Resources............................................................................................................................................................25
Lesson 7: Create and Use Resources...................................................................................................................................25
Module Review............................................................................................................................................................................................ 26
MODULE 3 KEY TAKE AWAY ..................................................................................................................................................................... 26
MODULE P RACTICE....................................................................................................................................................................................... 27
Practice 3: Create Labels........................................................................................................................................................................... 27
MODULE 3: Y OUR NOTES.......................................................................................................................................................................... 29
Module 4: Base Enumerations................................................................................................................................................................ 30
Lesson 1: Fleet Management Scenario................................................................................................................................30
Lesson 2: Create a Base Enumeration.................................................................................................................................30
Lesson 3: Best Practices......................................................................................................................................................31
Module Overview........................................................................................................................................................................................ 32
MODULE 4 KEY TAKE AWAY ..................................................................................................................................................................... 32
MODULE P RACTICE....................................................................................................................................................................................... 33
Practice 4: Create Base Enumerations................................................................................................................................................. 33
MODULE 4: Y OUR NOTES.......................................................................................................................................................................... 36
Module 5: Extended Data Types.......................................................................................................................................................... 37
Lesson 1: Fleet Management Scenario................................................................................................................................37
Lesson 2: Primitive Data Types............................................................................................................................................37
Lesson 3: Create an EDT......................................................................................................................................................37
Lesson 4: Best Practices......................................................................................................................................................39
Module Review............................................................................................................................................................................................ 39
MODULE 5 KEY TAKE AWAY ..................................................................................................................................................................... 39
MODULE P RACTICE....................................................................................................................................................................................... 40
Practice 5: Create Extended Data Types (EDTs)............................................................................................................................... 40
Module 6: Tables........................................................................................................................................................................................ 45
Lesson 1: Fleet Management Scenario................................................................................................................................45
Lesson 2: Create a Table......................................................................................................................................................45
Lesson 3: Adding Data Types...............................................................................................................................................46
Lesson 4: Key Properties.....................................................................................................................................................47
Lesson 5: Table Inheritance.................................................................................................................................................48
Lesson 6: Temporary Tables................................................................................................................................................49
Lesson 7: Queries................................................................................................................................................................ 49
Lesson 8: Best Practices......................................................................................................................................................50
Module Review............................................................................................................................................................................................ 52
MODULE 6 KEY TAKE AWAY ..................................................................................................................................................................... 52
MODULE P RACTICE....................................................................................................................................................................................... 54
Practice 6.1: Create Tables....................................................................................................................................................................... 54
Practice 6.2: Create Queries.................................................................................................................................................................... 56
Module 7: Table Indexes.......................................................................................................................................................................... 59
Lesson 1: Fleet Management Scenario................................................................................................................................59
Lesson 2: Index Types..........................................................................................................................................................59
Lesson 3: Create an Index....................................................................................................................................................59
Lesson 4: Best Practices......................................................................................................................................................60
Module Review............................................................................................................................................................................................ 60
MODULE 7 KEY TAKE AWAY ..................................................................................................................................................................... 61
MODULE P RACTICE....................................................................................................................................................................................... 61
Practice 7: Create an Index...................................................................................................................................................................... 61
Module 8: Table Relations....................................................................................................................................................................... 64
Lesson 1: Fleet Management Scenario................................................................................................................................64
Lesson 2: Relations..............................................................................................................................................................64
Lesson 3: Creating a Relation..............................................................................................................................................65
Lesson 4: Best Practices......................................................................................................................................................65
Module Review............................................................................................................................................................................................ 66
MODULE 8 KEY TAKE AWAY ..................................................................................................................................................................... 66
MODULE P RACTICE....................................................................................................................................................................................... 66
Practice 8: Create a Table Relationship............................................................................................................................................... 66
Module 9: Form Patterns.......................................................................................................................................................................... 69
Lesson 1: Form Patterns and Sub-patterns - Part 1.............................................................................................................69
Lesson 2: Form Patterns and Sub-patterns - Part 2.............................................................................................................70
Lesson 3: Form Patterns and Sub-patterns - Part 3.............................................................................................................72
Lesson 4: Layout Properties................................................................................................................................................73
Lesson 5: Check Form Pattern.............................................................................................................................................74
Module Review............................................................................................................................................................................................ 75
MODULE 9 KEY TAKE AWAY ..................................................................................................................................................................... 75
Module 10: Form Creation...................................................................................................................................................................... 78
Lesson 1: Fleet Management Scenario................................................................................................................................78
Lesson 2: Create a Form......................................................................................................................................................78
Lesson 3: Form Controls......................................................................................................................................................78
Lesson 4: Adding Elements..................................................................................................................................................80
Lesson 5: Best Practices......................................................................................................................................................83
Module Review............................................................................................................................................................................................ 83
MODULE 10 KEY TAKE AWAY .................................................................................................................................................................. 83
MODULE P RACTICE....................................................................................................................................................................................... 84
Practice 10.1: Create Forms..................................................................................................................................................................... 84
Practice 10.2: Adding Elements............................................................................................................................................................. 85
Module 11: Menus...................................................................................................................................................................................... 89
Lesson 1: Fleet Management Scenario................................................................................................................................89
Lesson 2: Creating Menu Items...........................................................................................................................................89
Lesson 3: Creating Menus...................................................................................................................................................90
Module Review............................................................................................................................................................................................ 92
MODULE 11 KEY TAKE AWAY .................................................................................................................................................................. 92
MODULE P RACTICE....................................................................................................................................................................................... 93
Practice 11.1: Create Menu Items......................................................................................................................................................... 93
Practice 11.2: Create a Menu.................................................................................................................................................................. 94
Module 12: X++ Overview...................................................................................................................................................................... 98
Lesson 1: Fleet Management Scenario................................................................................................................................98
Lesson 2: Code Editor..........................................................................................................................................................98
Lesson 3: Create a Runnable Class......................................................................................................................................98
Lesson 4: Intellisense..........................................................................................................................................................99
Lesson 5: Data Types...........................................................................................................................................................99
Lesson 6: Variable Declaration..........................................................................................................................................100
Lesson 7: Key Operators....................................................................................................................................................101
Lesson 8: Basic Syntax - Part 1...........................................................................................................................................102
Lesson 9: Basic Syntax - Part 2...........................................................................................................................................104
Lesson 10: Comparison Tools............................................................................................................................................105
Lesson 11: Debugger.........................................................................................................................................................105
Lesson 12: Best Practices..................................................................................................................................................106
Module Review.......................................................................................................................................................................................... 107
MODULE 12 KEY TAKE AWAY ............................................................................................................................................................... 107
MODULE P RACTICE.................................................................................................................................................................................... 112
Practice 12: Create a Runnable Class................................................................................................................................................ 112
Module 13: Classes.................................................................................................................................................................................. 114
Lesson 1: Fleet Management Scenario..............................................................................................................................114
Lesson 2: Class Structure...................................................................................................................................................114
Lesson 3: Create a Base Class............................................................................................................................................114
Lesson 4: Methods............................................................................................................................................................114
Lesson 5: Class Inheritance................................................................................................................................................116
Lesson 6: Best Practices....................................................................................................................................................117
Module Review.......................................................................................................................................................................................... 118
MODULE 13 KEY TAKE AWAY ............................................................................................................................................................... 118
Module 14: Database Manipulation.................................................................................................................................................. 121
Lesson 1: Fleet Management Scenario..............................................................................................................................121
Lesson 2: Data Retrieval....................................................................................................................................................121
Lesson 3: Reading Records................................................................................................................................................122
Lesson 4: Transaction Integrity Checking..........................................................................................................................123
Lesson 5: Data Insert.........................................................................................................................................................124
Lesson 6: Data Updates.....................................................................................................................................................126
Lesson 7: Data Deletion.....................................................................................................................................................127
Module Review.......................................................................................................................................................................................... 127
MODULE 14 KEY TAKE AWAY ............................................................................................................................................................... 128
Module 15: Exception Handling.......................................................................................................................................................... 130
Lesson 1: Fleet Management Scenario..............................................................................................................................130
Lesson 2: Exception Types.................................................................................................................................................130
Lesson 3: Key Commands..................................................................................................................................................130
Lesson 4: Code Statements...............................................................................................................................................131
Module Review.......................................................................................................................................................................................... 133
MODULE 15 KEY TAKE AWAY ............................................................................................................................................................... 133
Module 16: Security Basics................................................................................................................................................................... 136
Lesson 1: Security Architecture Overview.........................................................................................................................136
Lesson 2: Create a Role.....................................................................................................................................................138
Lesson 3: Create a Duty.....................................................................................................................................................139
Lesson 4: Security Properties on Key Elements.................................................................................................................139
Module Review.......................................................................................................................................................................................... 140
MODULE 16 KEY TAKE AWAY ............................................................................................................................................................... 140
Module 17: Introduction to Advanced Topics............................................................................................................................... 144
Lesson 1: Business Intelligence.........................................................................................................................................144
Lesson 2: Reporting Services.............................................................................................................................................145
Lesson 3: Services and Integration....................................................................................................................................145
Lesson 4: Data Entities......................................................................................................................................................146
Module Review.......................................................................................................................................................................................... 147
Module 0: Fleet Management Case Study
Throughout this course, we're going to progressively build upon the Fleet Management scenario. As we
proceed through the different lessons we will develop the case study further and further with
business requirements, demonstrations, and examples for each module.
The Fleet Management case study is a scenario designed to give you exposure to the main components and
elements of the development environment and Visual Studio. For our scenario, we have a company called
Contoso Entertainment Systems USA. They're going to extend their operations to manage their internal fleet of
vehicles.
In order to meet the business requirements, developers at Contoso will modify the application to meet those
needs. At a high level, the system will be used to track all fleet vehicle information
and service and maintenance of those vehicles.
So, in the screenshot, we have two tables and one is going to be a general vehicle table that contains
information like make, model and VIN number. Another table will have maintenance information, such as the
type of maintenance, date of service, parts used and so on.

Module 1: Introduction to Visual Studio

Lesson 1: Module Overview


Welcome to the first module of the course. In this module, we will introduce the development environment in
Visual Studio. Let's begin by reviewing the objectives. The objectives for this module are configuring and
setting up the development environment; defining important terminology and concepts; demonstrating basic
navigation within Visual Studio; creating projects, models, and packages; creating and using elements; and
finally, building elements for use within the system.

Lesson 2: Fleet Management Scenario


In this lesson, we will discuss the fleet management scenario for the introduction to Visual Studio module. For
the fleet management scenario, we need to complete the following five tasks. First, we'll configure the Visual
Studio environment for AX development. Second, we'll create a new packaging model. Third, we'll create a
project within that model to hold our elements. Fourth, we'll create an element within that project. And fifth,
we will build that project. The scenario is as follows: Simon, the system developer for Contoso, is tasked with
creating a new module for the fleet management system in Visual Studio.

Lesson 3: Setup and Configuration


The first time you use Visual Studio to develop with AX, you will need to complete some basic configuration. In
this lesson, we'll look at some settings to configure before we can begin using Visual Studio. First, let's take a
quick look at some of the system requirements for using Visual Studio to develop with AX. The first thing to
note is it can be hosted locally or in the cloud using Microsoft Azure. Secondly, a minimum of 16 gigabytes of
RAM is recommended along with two CPU cores for a smooth development environment. However, the more
RAM and CPU cores you have will translate into faster compile times. There are a few settings we want to
configure in Microsoft Visual Studio that will make the development experience with AX a little smoother. The
first option we want to set is to organize projects by element type. To do this, we'll go to the Dynamics AX
menu and we'll choose options. In the left navigation pane, under the Dynamics AX group, we want to expand
that and choose projects. The first checkbox says organize projects by element type. We want to make sure
this is checked so that when we create projects and we add elements, they're organized and easier to find. The
next setting from the same options is in the text editor group. So we'll expand this and we'll go to all
languages. We want to make sure that line numbers checkbox is enabled so that in our text and code editors,
we can see the line numbers. This makes it easier for development and debugging. The next setting is in the
IntelliTrace group. So we'll click the root node on the IntelliTrace group and we'll uncheck this enable
IntelliTrace option. We do not want this enabled because it's not supported with X++ debugging and it could
cause performance issues. So we'll uncheck this and choose OK and then we'll restart Visual Studio to make
sure our changes are taking effect.

Lesson 4: Terminology and Concepts


In this lesson, we will discuss the terminology and concepts related to the development environment in Visual
Studio. Four main components to understand in Visual Studio include elements, models, projects, and
packages. Here, we're looking at a screen shot of the Application Explorer. Within it, there's an AOT node. All
of the sub-nodes below the AOT node are different models. This is called model view. We can switch between
model view and classic view by right clicking this AOT node and selecting the appropriate view. Each of these
models contains its own set of system elements. If we expand one of them, we would then see the underlying
elements such as data types, tables, and classes that relate to that model. The package name that the model
resides in is located in parentheses to the right of the model name. Elements in Dynamics AX are the objects
that reside in the AOT and the Application Explorer. Some examples of elements are tables and forms.
Collectively, these elements are what define the system and dictate what the user will see in the front end.
Elements can be customized once they are added to a specific project or model. A Dynamics AX model is a
group or collection of elements that represent a distributable software solution. A model is a design time
concept. For example, there could be a model on warehouse management or fleet management. A particular
model may contain multiple Visual Studio projects. However, a project may only belong to one model. A
Dynamics AX package is a deployment unit that may contain one or more models. In addition to elements, it
includes model metadata, which is description data that defines the properties and behavior of the model. A
package can be exported to a file which can then be deployed into a staging or production environment.

Lesson 5: Naming Convention


In this lesson, we'll discuss best practices for naming your elements in projects. When naming elements, it's a
best practice to use camel case. For example, in our development basics fleet management example, we'll
prefix our elements with DB. So we can have an object like DB table name or DB class name. We also want to
make sure we're maintaining consistency throughout the model and throughout the system so that our
elements are easy to locate and easy to find when we need to edit them. We also want to avoid reserved
keywords. These are words the system uses. And lastly, we want to prefix with a company name or a project
name so that, again, things are easier to find in the system. For example, if we are creating elements related to
a customer, we can prefix them with cust. So we're going to prefix our development basic elements with DB.
So for example, when we create the dbVehicle table later in the course, we'll call it dbVehicle. We're going to
adhere to this prefixing convention when creating additional elements for our fleet management project such
as forms, classes, extended data types, and so on. In addition to prefixing element names, it's also wise to
prefix company-specific elements. For example, if you have multiple companies, it makes them easy to identify
which company those elements belong to.
Lesson 6: Navigation
In this lesson, we will explore the various areas and menus within the Visual Studio development environment
for Dynamics AX. We will explore the major areas of the development environment which include the
Application Explorer and AOT, which is known as the application object tree. And within the AOT, we'll look at
the model view so we can see the organization of the different models in the system, and then we'll look at
how the elements are organized within the AOT. Next, we will look at the Solution Explorer window which is
where our projects and elements will be located. Then we'll check out the properties window which is where
we set properties on our different elements. We'll check out the code editor so we can see how X++ code is
developed and edited in the environment. And lastly, we'll look at the Dynamics AX menu. From here, we can
do different tasks such as creating models. First, let's take a look at the Application Explorer. By default, when
you open Visual Studio, you might have some windows and panes already populated here. I'm starting with a
blank canvass so I can show you how to enable or disable certain navigational features. So the first thing we
want to do is go up to the view menu. And we're going to demo the Application Explorer. So I'm going to
click it and it will appear here on the left. I'll right click the AOT node and choose classic view and we'll look at
how this is set up first. The classic view contains all of the system elements regardless of which model they are
in. So we can see the data types node is the very first one in the list. If we expand that, we have our base
enums and our extended data types. If we expand the data model node, we can find our tables, views, queries,
data entities, as well as table maps and table collections. Under the code node, we have our classes and
macros. The user interface node is where we'll find things like forms, tiles, which is a new concept that we'll
discuss in this course, as well as menus and menu items. So these are the user interface and navigational
components of AX. We also have an analytics node. This is where our BI pieces will be located. So we have
KPIs. We also have perspectives and some new concepts here such as aggregate dimensions, aggregate
measurements. Under the reports node is we will find our SSRS reports as well as our report data sources and
any images that are used in reports. Our label files are located in the labels node and our resource files are
located in the resources node. We also have a node for security as well as for references and services. Now
we'll switch to the model view. And we achieve this by right clicking on the AOT node and choosing model
view. Now we see an organization by every model that's currently in our system. And the parentheses is the
name of the package that that model belongs to. So if I expand at the Application Suite model, we can see it
contains all the same nodes that we saw in the previous view except for it's only going to have the elements
that are related to this particular model. We also have this search box up here in the Application Explorer
where we can search for elements within the system. One thing we can do is use the word type, followed by a
colon, and then specify the element type. So I'm going to look for a table and we can see my recent search
history of the cust table. So when I enter this search query, it's going to return a list of all the elements that
have cust table in it of type table. So once you choose an element, it's going to tell you the model that it
belongs to here in the brackets. We can right click in the element and choose add to new project. Since I don't
have a project open, it's going to create a new project with this element in it in the Application Suite model. So
once you add an element to a new project, you'll be prompted to enter a project name. And choose OK. And
once we add an element to a project, you'll notice the Solution Explorer window appears without project name
and a folder for the type of element and then our actual element. So now we have our Solution Explorer
window open. This can also be accessed from the view menu and choosing Solution Explorer. The Solution
Explorer contains our project that we just created. It's called the new table project, and we can add multiple
projects to this solution which is called new table project up here. Within our project, we can add new folders.
So if we right click the project name, we can go to add and choose new folder, depending on how we want to
organize our project. By default, every time we add an element to this, it's going to add it to the
corresponding element type folder since we set that setting in the configuration step to organize our projects
by element type. Once we select an element, we have our properties window down here which will display and
show the different properties we can set on that element. So for example, we're selecting on the cust table and
we can change the label, we can change different behaviors and settings on this table by using the properties
window. The properties window, as well as all of these windows, can be set to float or set to docked. We can
also hide different windows and arrange them as we please. Everything is free form. We can also save a
window layout when you have the different windows set up how you like by choosing window and save
window layout. Next, let's look at the code editor window. So we'll go back to the Application Explorer, and I'll
choose type class and I'll look for classes with the word cust in it. So once you have a code element such as a
class or macro or method, we can right click it and choose view code. This will open the code editor window
and you're free to edit and save this code. We can also choose any class and press F7 which will also launch
code editor window. Now, we can see I have two different tabs here with the two different classes that I'm
currently modifying. The last piece of the navigation components we want to look at is this Dynamics AX
menu. From here, we can choose to deploy a package. We can also set options for model management. This
includes creating models, updating a models parameter, such as its name. We can also import projects as well
as set different options in the system.

Lesson 7: Projects, Models, and Packages


We've looked a little bit at how projects and models work with each other in the Visual Studio development
environment. Now let's look at how to create model to use for our fleet management scenario. We defined a
model as a collection of elements that represent a distributable software solution. Creating a model involves
specifying metadata like the model's name and description. We can create a model using a wizard. And when
we create a model, we have the option to choose whether we want to create that model in a separate package
or in an existing package. These two choices will determine the development approach that we'll be using. If
we create a model in a separate package, that implies we will be using the extension development approach. If
we create a model in an existing package, that means we'll be using the overlayering or customization
development approach. Next, we'll look at how to update model parameters after we have created a model,
and we'll look at how to view a model's dependencies, that is what other models it is dependent upon. These
are also called referenced models. So first, we'll use the wizard to create a model for a fleet management
scenario and then we'll create projects to associate with that model. In AX, we have two options for
approaching development. Those are overlayering and extensions. If we choose to create a model in an
existing package, you must select a model that contains the elements you wish to customize as a referenced
model in the wizard. This way your new model has access to those elements. Taking this approach allows you
to customize metadata and source code at a higher layer. For example, you can change the design of a form in
the user layer. However, this method could potentially increase the cost of upgrading to new versions of AX in
the future. If we choose to create a model in a new package, this implies we're going to use the extension
model approach. Developing this way allows us to access the elements from any models that we selected as
referenced models and the wizard. It also allows us to add functionality to existing code. We can create new
elements as well as create extensions of referenced elements in our projects. By creating extension elements,
all of the customizations and code are stored in a separate assembly. It only contains the code that was added
or changed in the extension file. Since this code resides in a separate assembly, it improves performance and
the ability to upgrade and test. This approach is also ideal when it comes to upgrading so we can eliminate
metadata conflicts in our code. Developing using the extension model will be discussed in greater detail in
advanced development courses. So let's begin by creating a new model that we can use for our fleet
management scenario. And then we'll create a project to associate with our model. To create a new model,
we'll going to the Dynamics AX menu, and under the model management group, we'll choose create model.
This opens the model wizard. And from this window, we can specify our model name. So we were going to
call ours DBFleetManagement. We'll give it a short description. And then this also the model display name
that we'll see in the Application Explorer in the AOT. So we'll leave that as DBFleetManagement. And for the
publisher, we can stick our name in there. And then we'll choose the next button. Now we're presented with
this option if we want to create a new package for our model. And again, this implies we'll be taking the
extension development approach. If we choose select an existing package, this means we'll be using our
overlayering or customization development approach. For our fleet management scenario, we're going to
create a new package so we're going to use the extension development approach. So I'll choose an option and
select next. Now, here is where we are going to select our referenced models, which means which other
models are our new models going to be able to see or which elements it's going to be able to access. So there
are some system models such as Application Platform, application foundation, and Application Suite that host
a lot of the tables like the customer table, the vendor table. So for the purpose of our scenario, we'll just leave
it at the Application Platform and we'll choose next. We'll be presented with a summary window of our model
name and display name. And we're going to have this checkbox to say, hey, let's create a new project right
away to start building and adding elements. So we'll choose finish. And now we're prompted to give a name
for our new project to associate with our new model. So I'll call it DBProject1. And choose OK. So now we
have our new model and our new project and we're ready to begin adding and customizing elements. Once
we have our model created, we can also go back and update the model parameters at any time. To do this,
we'll go to the Dynamics AX menu. Under model management, we can choose update model parameters. And
this will bring us back to the wizard screen. So the first thing we have to do is select our module name from
the drop-down. The model that we want to modify. So we just created our DBFleetManagement model. We'll
select that and we can see it brings up the details about that model. So we can change the display name, the
description, and the publisher on this screen. We cannot change the actual name. If we hit next, we can now
change the dependency information. So if we want to add another model as a dependent model so we can
access the elements from that model, we would do that at this screen by selecting the checkbox next to the
model we want. So for this particular model, I just have the Application Platform as a referenced model. So
once we complete going through the wizard again, we'll get a summary screen and we can choose finish.
Another important thing to know from the Dynamics AX menu is this option under model management to view
package dependencies. This is going to open up a DGML file which is a graphical file that shows all the
dependencies of the different models in the system. Now, if I zoom in using my scroll wheel, we can see here's
my DBFleetManagement model that we just created. We can hover over it for some information. We can also
click it, and it's going to give us that basic summary information that we just saw in the wizard. And we can see
that it points to the Application Platform. This is the referenced model that I selected and this is the only
referenced model that I had selected so we could see here this relationship between my DBFleetManagement
model and the Application Platform model. We can also scroll around to see all of the different relationships
that exist between the different models. When working with projects, it's important to note that each project
can only contain elements from one model. If you need to use elements from multiple different models, a new
project will be created for each set of elements that originates from a different model, or you have to have your
model configured to reference the models you need. When we want to customize elements, we can add them
to our project from the Application Explorer in the AOT by right clicking the element and choosing add to
project. In the next demonstration, we'll look at creating projects and adding them to solutions as well as
setting the properties of the project. And then finally, we'll look at adding elements to our projects. The
diagram below gives an overview of the different properties that we can set on a project. Of these properties,
the model property is particularly important. You must specify which model your project is to be associated
with. All of the elements in the project must be in the selected model. The startup object type is another
important property to note. When you want to test or debug your application, you set the startup object type
as the type of element you wish to debug. For example, if you want to test a form you're developing, we would
set the startup object type as form. And then the startup object property specifies the specific form that you're
going to be setting as your startup object. We can run a project by pressing CTRL F5 and it will invoke the
startup object when you run that project. Another property to note is a synchronized database on build
property. This simply specifies if you want to perform a database synchronization when a build action is
performed on the project. When we created a new model, it automatically gave us the option to create a new
project with that model. If we want to create a project manually, we can also do that. We currently have the
solution DBProject1 open with a project called DBProject1. If we right click the solution from the Solution
Explorer, we can choose add and hit new project. This will add a new project to the same solution. We can
also go to the file menu and choose new and project. We'll choose Dynamics AX project, and then we can
specify a name for our project. We'll call this DBProject3. And then from this drop down here, we can specify
again if we want to add this project to the currently open solution or if we want to create that in a new solution
file. We could also import and export project package files. A project package file contains all of the elements
from a project. We can use these package files to import and export between different instances of AX. A
project package file is saved with a .AXPP file name extension. To export a project, we go to the project menu,
and we choose export project. This will export the currently open project with all of the elements along with it.
Since this current project does not have any elements with it right now, it will not let us create an export.
However, we would go in here and specify a name for the project package and choose save. Then, when you
want to import a project, we go to the Dynamics AX menu and we choose import project. From here, we can
choose a file path and some other options for the import. For this example, I'm going to choose an AXPP file
that I have on my local disk here. I'll load it in and it will come up here with all the details of the different
elements in this project. If I keep expanding, we can see all the different XML files that relate to each element
in that project. We also have the option to open the project in the current solution or a new solution as well as
to overwrite elements if they already exist. An important thing to note when importing projects into other
instances of AX is that if you have a project associated with a model that you export, and then you want to
import it into another instance of AX that does not have that model created, the project import process will
automatically create a model for that project.

Lesson 8: Using Elements


So we've talked a little bit about where elements are located in the Application Explorer and the AOT and how
they're organized. So let's take a deeper look at how we work with elements and customize them within our
projects. When editing elements, we use what's called the element designer to configure the properties and
set different options for that element. For example, we can add fields to a table using the element designer.
We could then set properties on those fields and tables using the properties window. We can also find related
elements by right clicking in a particular element and finding other elements that may relate or associate to
that one. Here's a screen shot of what the element designer looks like. It opens in a tab in Visual Studio and
allows you to customize the element. So here, we're looking at a table called FMCustomer. It belongs to the
model fleet management. It contains all the various pieces that we can change on a table such as fields, field
groups, relations, and indexes. And we'll look at all these concepts later on in the course. It's important to
note that all development is done against local XML files. These XML files are stored on your local disk in
folders organized by package and model. The actual XML file contains both the metadata for an element as
well as any source code for an element. This means when you customize a table, for example, it will store the
properties of the table such as the name and the table type along with any X++ code written for that table all
in a single XML file which is stored locally. Here's a view of a properties pane for a particular element. If we
select the element, the element type and name will appear here at the top of the properties window. And then
within the properties pane, we can scroll up and down and see all the different properties available here for
editing this element. They can be organized in different ways. So currently, the property's organized by
category. So we have a category called data and then all the properties that relate to changing the data of that
element. We can also have these properties organized by frequency of use as well as alphabetically. So this
properties window contains details about the highlighted top-level node, in this case, is our table, the
FMCustomer. There are several ways to add a new element to your project. We can right click the project from
the Solution Explorer. And we can choose the add option, and then we can choose new item. We can also use
a shortcut key, CTRL SHIFT A, to add a new item to the project. Now, in the middle pane, it's going to show an
alphabetical list of all the different element types or artifacts that we can add to our project. These are all AX
elements. I'm going to click table and I'll give it a name here at DB table and choose add. And you'll notice it
will automatically create a folder called tables so that each successive table that we add will be organized in
this folder. And it opens up the element designer by default. So now, I can go in here and right click on fields
and add fields to my table. And I could add a different primitive data type. We can also choose our element
and press ALT enter to bring up the properties pane here if it's not already visible in your window layout. So
once you add an elements, you can go ahead and begin editing it using the element designer tab as well as
changing the properties on it. We can close out the element designer by choosing the X on the tab here. And
we can reopen the element designer by right clicking in the element and choosing open. This will bring back
our designer. Now, if you notice on the left, we're looking at our model view, so these are all the different
models in the system. This current project is associated with the DBFleetManagement model. So if I were to
go into another model, for example, the Application Foundation, and I tried to add one of these base enum
data types to my project, I can right click the element and you'll notice the add to project is grayed out. That's
because this current project is associated with a different model. Since we're using the extension development
approach, I cannot add an element from a different model into this current project that's associated with
another model. There are options, however, to add to a new project will create a new project connected to this
model where this element lives. If we go to our DBFleetManagement model, we don't really have any elements
in here yet besides this table that I've just created and added to our project. So if I go to the data model node
and expand tables, we can see there's my DB table. So once you have an element in your model, you can drag
it over to your project. You can also right click and choose add to project. Since we already have this element
in our project, we don't need to add it any further. It's just important to note that when you're adding
elements to your project, they need to be in the model that your project is associated with.

Lesson 9: Performing Builds


When we create new models and projects that contain new elements or customized elements, we need to build
them so that they can be used by the application. The elements of a model must be built so that they can be
used by the application. A full build can be performed on an entire model or multiple models. A build can also
be performed on a project, meaning it will only build the elements that are in the current project. When a build
is done on a project, it will only build the elements that are new or changed since the last build was performed.
So during a build operation, various validations are performed. So metadata and X++ code will be validated.
A best practice check can be performed. Report design generation will be completed. Compilation and
creation of .NET assemblies is also done in a build, as well as label and resource file generation. And lastly,
database synchronization can also be done in a build. And we'll take a look at the different options we can set,
what we want to encourage during a build process. For example, if we don't want a database sync to occur
during a build, we can specify that before we perform it. So in order to perform a build on our project, we can
go up to the build menu, and we'll choose build DBProject1, which is our currently open project. An output
window will display, giving the status of the build as well as each step being performed. When we choose to
do a build, it only builds new or changed elements. It's important to note that if we delete an element from a
project, we must use the rebuild option in order for that deletion to take effect. Performing a rebuild also
forces a build of all objects in the project regardless of whether they have changed or not. So for example, if I
wanted to delete my DB table, I can right click and choose delete. And now, I will have to go to my build menu
and choose rebuild DBProject1 in order for that deletion to take effect. And I'm here in my output window,
and it says that the rebuild has succeeded. We can also perform builds by right clicking on our project name
from the Solution Explorer and choosing build or rebuild. If we want to build an entire model, we can go to the
Dynamics AX menu and choose build models. And from here, we can put a checkbox next to every model that
we want to build along with the option to build the referenced models. If we go to the options tab, here's
where we can select what we want to happen during the build process. So we have the option to run a best
practice check, to perform a database synchronization, as well as build reports and precompiled forms and
cross-reference data. Lastly, if we right click our project and choose properties, we can go through the
different options for the project. And at the bottom, we'll notice again synchronize database on build.
Currently, by default, it's set to false. But we can flip this to be true if we want a database sync to be performed
each time which build it. It's set to false for performance reasons, so it's not performing this sync each time we
do a build. However, the choice is yours to make.

Module Review
In this module, we learned how to set up and navigate the development environment in Visual Studio for
Dynamics AX. We defined some important terminology and concepts and we learned a bit about naming
conventions. Then we looked at how to create packages, models and projects, as well as creating elements and
adding them to our projects. Finally, we covered the different options and methods for building our elements
for use within the application.

MODULE 1 KEY TAKE AWAY


o Introduction to Visual Studio

 Setup and Configuration

 System Requirements

 Hosted locally or on Microsoft Azure

 Minimums:

o 16GB RAM

o 2 CPU cores

 More RAM & CPU = Faster compiles

 Terminology and Concepts

 Elements

 Objects residing in AOT

 Tables and forms


 Customizable

 Models

 Group of elements

 Design time concept

 Projects

 Contained inside models

 Can only be associated with one model

 Packages

 Deployment unit that contains models

 Naming Conventions

 Camel case

 Maintain consistency

 Avoid reserved words

 Prefix with a company/project name

 Example: DBVehicle

 Navigation

 Application Explorer and AOT

 Model View

 Solution Explorer

 Properties window

 Code editor

 Dynamics AX Menu

 Projects, Models, Packages

 Creating a model with the wizard


 Overlaying vs. Extension

 Create model in existing package

o Allows customization of metadata and source code in higher layer

o Could increase cost upgrade to newer AX versions

 Create model in a new package

o Allows access to elements from any selected referenced models

o Can add functionality to existing code

o Create new elements and extensions of referenced elements

o Improves performance of building and testing

o Ideal for upgrades

 Updating model parameters

 Project properties

 Most important = model property

o Must specify which model the project is associated with

 Startup object type and startup object properties

o Useful for testing and debugging

 Using Elements

 Element designer

 Finding related elements

 Setting element properties

 Can be organized in various ways

 Contains details for highlighted, top-level node

 Performing Builds

 Building operations
 Metadata and X++ code validation

 Best practices check

 Report RDL generation

 Compilation and creation of .NET assemblies

 Label and resource file generation

 Database synchronization

MODULE PRACTICE
Practice 1.1: Configure Visual Studio
Scenario
For the introduction to Visual Studio for the fleet management scenario we will need to complete the following
four tasks in the next four practices.
 Configure the VS environment for AX development.
 Create a new model, package, and a project.
 Create an element within the project.
 Build the project.

Simon, the Systems Developer for Contoso, is tasked with creating a new model for the Fleet Management
System in Visual Studio. He is to ensure that it is ready for element creation and that the project builds.

High Level Steps


1. Open Visual Studio
2. Set Text Editor Options
3. Set Best Practice Options
4. Set Projects Options
Detailed Steps
1. Right Click on the Visual Studio icon on the desktop and select Run as Administrator.
2. Open Dynamics ‘AX7’ > Options.
a. Expand Text Editor node
b. Select All Languages node, under Settings:
i. Select the Word wrap check box
ii. Select the Line numbers check box.
c. Collapse the Text Editor node
d. Expand the Dynamics ‘AX 7’node
i. Select Best Practices node and check the following:
1. Microsoft.Dynamics.AX.Framework.BestPracticeFramework.UIRules
2. Microsoft.Dynamics.AX.Framework.CodeStyleRules
3. Microsoft.Dynamics.AX.Framework.DataAccessRules
4. Microsoft.Dynamics.AX.Framework.DataEntityRules
5. Microsoft.Dynamics.AX.Framework.DeprectatedElementsRules
6. Microsoft.Dynamics.AX.Framework.MaintabilityRules
7. Microsoft.Dynamics.AX.Framework.StaticCodeValidationRules
ii. Click Projects node under the Dynamics ‘AX 7’ node.
1. Verify that the Organize projects by element type check box is selected, and
click OK.

Practice 1.2: Create a Project


Scenario

Simon, the Systems Developer for Contoso, is tasked with creating a new model for the Fleet Management System in
Visual Studio. He is to ensure that it is ready for element creation and that the project builds. This practice is in
continuation of the previous practice

High Level Steps


1. Run the Model Wizard
2. Set the Model parameters
3. Create a new package with selected reference models
4. Create a project

Detailed Steps
1. Right Click on the Visual Studio icon on the desktop and select Run as Administrator.
2. On the Visual Studio menu, click Dynamics ‘AX 7’
3. Click Model Management > Create Model
a. Model name: DevelopmentBasicsFMS
b. Model publisher: AX Developer
c. Layer usr
d. Version 1.0.0.0
e. Model description: Example Fleet Management System for Development Basics to illustrate and
practice development tasks.
f. Model display name: DevelopmentBasicsFMS
4. Click Next
5. Select Create new Package
6. Click Next
7. Select the following referenced models
a. Application Platform
b. Application Foundation
c. Application Suite Electronic Reporting Integration, Application Suite
d. Application Platform Form Adaptor
e. Application Suite Form Adaptor
f. Application Workspaces
g. Application WorkspacesFormAdaptor
8. Click Next
9. On Summary, ensure check boxes are checked for:
a. Create new project
b. Make this my default model for new projects.
10. Click Finish
11. Select Dynamics AX7 Project
12. Enter DevelopmentBasicsFMSProject in the Name field.
13. Click OK

Practice 1.3: Create an Element


Scenario

Simon, the Systems Developer for Contoso, is tasked with creating a new model for the Fleet Management System in
Visual Studio. He is to ensure that it is ready for element creation and that the project builds. This practice is in
continuation of the previous practice

High Level Steps


1. Create an element
Detailed Steps
1. In the Solution Explorer, right click DevelopmentBasicsFMSProject
2. Click Add > New Item
3. Under AX7 Artifacts, select User Interface
4. Select Menu
5. Name: dbfmTestElementMenu
6. Click Add

Practice 1.4: Build and Compile


Scenario

Simon, the Systems Developer for Contoso, is tasked with creating a new model for the Fleet Management System in
Visual Studio. He is to ensure that it is ready for element creation and that the project builds. This practice is in
continuation of the previous practice

High Level Steps


1. Run the Build process
2. Review the results
Detailed Steps
1. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
2. Click Build (or use Ctrl+Shift+B)
3. Review the Output screen to review the process. Should say “Build: 1 succeeded or up-to-date”.
MODULE 1: YOUR NOTES
Module 2: Architecture
Welcome to Module 2 on architecture. In this module, we will review the high-level architecture that is used in
AX. Let's get started by reviewing the objectives. The objectives for the architecture module are to describe
the elements included in the application stack, to review the server architecture, and to explain the cloud
architecture used with AX.

Lesson 1: Application Stack


The application stack and server architecture in AX is designed to align with three key pillars, which include the
web-based client, cloud readiness and the Visual Studio development stack. The application stack has been
divided into three distinct models. The Application Platform, the Application Foundation, and the Application
Suite. This is for overview purposes and does not represent the actual model hierarchy within Visual Studio.
Let's start at the bottom of the diagram with the Application Platform. This is the core application. In this
layer, we have the runtime and data access which stores the core business logic that AX operates from. We
also have workflow and services which allow you to integrate other programs and run configurable business
processes through your defined flows and review and approvals. Next, we have the client and presentation
component. This layer creates the graphical user interface. This is the web-based application that users will
navigate to and use on a daily basis to perform their job functions. And finally, we have the SSRS reporting
component. This is used to present operation reports in the rich client using SQL Server reporting services.
The Application Platform technology is used to support the core functions of AX that the Application
Foundation is built upon. In the Application Foundation, we have things like the organizational model. This
supports visual modeling of your organization entities such as business units and departments. Next, we have
number sequences. This supports logical numbering of your data and documents through the system. For
example, the automatic numbering of sequential purchase orders. Next, we have the global address book.
This is used to design and centralize and share address information for various entities such as customers,
vendors and employees within the system. Finally, we have the source document framework which supports
documents such as purchase orders and free text invoices just as a few examples. And finally, we have the
Application Suite. The Application Suite is rich in functionality and includes things like financial management,
inventory and warehouse management, as well as human resources management and much more. The
application can also be extended to include customized applications which we'll be doing throughout the
course with our fleet management example.

Lesson 2: Server Architecture


In this lesson, we will review the server architecture. Starting from the bottom, the aggregate data store and
database are at the lowest level. Next comes the data access layer. This enforces a security to the underlying
data store and the database. The group of objects included on this layer include the metadata and other
components such as security, workflow, batch engine, and caches. These can directly relate to the OData
service endpoints or to the forms engine which is ultimately used for the user interface interaction layer. The
services endpoints on the server is responsible for returning all form and controls metadata as well as other
data to the browser-based client. The form objects run in the server and are rendered for a browser and other
clients. The server, including the application code base, is deployed to an IIS web application. In the cloud, it's
deployed to the Azure infrastructure as a service virtual machines. The metadata subsystem incorporates the
compiler and Visual Studio-based development model. The model store is represented as a set of folders and
locally stored XML artifacts organized by model. The Dynamics AX preview model elements, like tables, forms,
and classes, are represented by an XML file containing both metadata and source code.
Lesson 3: Cloud Architecture
In this lesson, we'll review how the cloud architecture functions with AX. The cloud architecture includes
services that automate software deployment and provisioning, operational monitoring and reporting, and
seamless application lifecycle management. The cloud architecture consists of three main conceptual areas.
The first is lifecycle services. This is a multi-tenant shared service that enables a wide variety of lifecycle-related
capabilities for Dynamics AX. Capabilities specific to this release include software development, customer
provisioning, service-level agreement monitoring, and reporting capabilities. The next component is Dynamics
AX. AX virtual machine instances are deployed through lifecycle services to your provided Azure subscription.
Different topologies are available. Demo, development, and test environments, and high availability
production topologies. The third component is shared services. AX uses a number of Microsoft services to
enable a one Microsoft solution where customers can manage a single log-in, subscription management, and
billing relationship with Microsoft across Office 365, PowerBI, and other online services. Dynamics AX uses
many features of the Windows Azure platform including Azure storage, networking, monitoring, and Azure SQL
databases. Shared services operationalize and orchestrate the application lifecycle of the AX environments for
participants. Together, Azure functionality and lifecycle services built for Dynamics AX offer a robust cloud
service.

Module Review
In this module, we described the components included in the application stack. We reviewed the server
architecture. And we explained the cloud architecture that is used in Dynamics AX.

MODULE 2 KEY TAKE AWAY


o Architecture

 Application Stack

 Application Platform

 Core of application

 Runtime and data access

 Workflow and services

 Client and presentation

 SSRS reporting

 Application Foundation

 Organization model

 Number sequence
 Global address book

 Source documents

 Application Suite

 Server Architecture

 Architecture

 Aggregate data store

 Database

 Data Access Layer

 Metadata

 Security

 Caches

 Workflow

 Batch

 Forms engine

 UI Interaction layer (WCF)

 OData Endpoint (WCF)

 Server deployed to an IIS web application

 In cloud deployed as service Virtual Machines

 Model stores are set of folders and XML artifacts

 Organized by model

 Cloud Architecture

 Lifecycle services

 Capabilities:

o Software development
o Customer provisioning

o Service level agreement monitoring

o Reporting capabilities

 Shared services

 One Microsoft

o Single login

o Subscription management

o Billing relationship with Microsoft

 Office 365

 Power BI

 Online services

 Dynamics AX

 Deployed through lifecycle services to Azure subscription

 Different topologies

o Demo

o Development/test

o High-availability production topologies:

 Demo

 Development/test

 High-availability production topologies

 Microsoft Azure

o Azure storage

o Networking

o Monitoring
o SQL Azure

o Etc.
MODULE 2: YOUR NOTES
Module 3: Labels and Resources
Welcome to Module 3. In this module, we'll learn about labels and resources. The objectives for this module
are to learn about labels and why we use them in AX. We will review the purpose of the labels for our fleet
management scenario. And then we will create and use both label files and labels. We will explore the search
capability of the label editor, and we will review the best practices for using labels. And finally, we will learn
about resources. And we'll create some and use them in our fleet management scenario.

Lesson 1: Labels
In the first lesson, let's discuss using labels. Label files are small data structures that keep all related and new
labels in a central storage file. For example, you can have a label file for your instance of AX, for your specific
company, or simply for a model. Labels themselves are a reference from the element or artifact in the system
that point back to the label file. This way, labels can have multiple versions depending on language settings.
They could return the correct value depending on the specified language in the system. This is also a more
efficient tool than hard coding values. For example, say a company now uses the term team member instead
of employee. When we update the label, the change is propagated to everywhere in the system where
employee is currently used. You should use labels to specify the user interface text for forms and reports.
Labels are created in the label editor and then used in text-based properties in the AOT or in X++ code.

Lesson 2: Fleet Management Scenario


In this lesson, we will cover labels and label files in the fleet management scenario. For the fleet management
system, there will need to be two items created. First, there will need to be a label file to hold the labels that
are included for the fleet management model. Second, for all of the artifacts and elements you create, they will
each need their own label.

Lesson 3: Create and Use Labels


In this lesson, we will review the creation and use of labels. Let's take a look at a demonstration of how to
create a label file and then a label within that label file. Since this is the first artifact or element we are going to
be using in our fleet management scenario, I'm going to start off by creating a new project that we will use
going forward. So I'm going to go to file, new and choose project. And we'll make sure we choose Dynamics
AX project, and we'll call this DB FMS project. Let's going to be our development basics fleet management
system project. OK. So once we have this new project loaded, we can begin adding our elements. So in my
Application Explorer, I'm currently looking at the classic view, which is all the system elements. So I'll right click
and switch to model view. And you notice that my Solution Explorer is not visible because I've closed it. So I'm
going to go back to view and Solution Explorer. And here's my newly created DB FMS project, and now I'm
going to begin adding elements. So to add a label file, you can right click our project. We'll go to add and
then new item. Now, again, in the middle pane, all the different available elements are organized in
alphabetical order. In the left pane, we can see them broken out by group. So I can click labels and resources,
and I want to make a label file. We'll call this DB -- let's call it DB demo label file. And I'll choose add. And
now it brings up the label file wizard. So I'll leave the label file ID as what I just specified in the previous step
and choose next. On this page of the wizard, we have the option to choose different languages to associate
with our label file. For this example, I'm going to keep the default, United States English language. And I'll
choose next again. And then finally, we'll choose finish to create our label file. So we can see it's created a
folder for a label files and then it's created this actual label file here. Now, to create a new label in the label file,
we would right click our label file here which ends in a .txt extension. And we'll choose open. This is going to
open the element designer for the label file. And here, we have the ability to search and add new labels. So I
simply click in this box here where label ID and I'll type in a label ID for a label file such as DB label one. I can
tab over to the next column, which is label. This is what the actual label will be, so we'll call it vehicle example.
I'll tab over to the description column, and I can add some more details. We'll just say label demonstration. So
those are the high-level steps of adding a label file and an actual label to a project.

Lesson 4: Search Labels


In this lesson, we will review how to search for labels. Now I'm going to demonstrate how searching for labels
works in Visual Studio. So I have my label file designer opened. I achieved that by right clicking on the label
file and hitting open and it opens this tab here with my label file and all of the labels contained within it. So we
can, you know, add new labels and delete labels from here. And we can also search. There's three options for
searching. We can search by text, by the entire word, or to match exactly. So for example, we see I have this
label ID DB label one. If I type DB and L, that label still shows because I'm just searching by text and DB L is in
this string here. If I were to type a letter like Y, for example, no matches match this particular combination of
letters. We can also search for strings or words in the label column and the description column. So if I were to
type in demonstration, this label is still returned in my search results. Likewise, if I choose match word, the
demonstration word appears right here in the description column, so it's going to still yield this result.
However, if I backspace, that entire word is no longer in my results.

Lesson 5: Best Practices for Labels


Let's review some best practices to consider when using labels. The following are the best practices for using
labels. You should use labels for every element or artifact that you create. You should ensure that labels
contain the appropriate translation of activity or item. Use labels when programming for all external strings.
Create a label file with the same name as the associated model. And before you create a new label, always do
a get latest on the label file you are editing. This ensures you have the most up-to-date and recent version of
the label.

Lesson 6: Resources
In this lesson, we will discuss how resources are created and used. Resources are the way to manage the
pictures, icons, and other visual representations that will be used within the user interface. This can be
accessed through the resource library, adding additional resources or using resources that are at a URL
location. The URL location would be used in the case of an IIS server instance with an established product
photo library.

Lesson 7: Create and Use Resources


In this lesson, you will create and use resources. The basic flow for creating and using resources is outlined in
this diagram. We will go to the Solution Explorer and locate our project. We will choose to add a new item to
the project of type resource. Once the resource is added, we can specify and locate which image file we want
to use for our resource. You can also hover over the resource to display a small thumbnail preview of the
image file that it contains. Finally, we want to change the name of the resource and set the label property
appropriately. So let's take a look at the process for adding a resource or an image file to our project. To do
this, we'll go to the Solution Explorer and right click our project. Again, we'll go to the add and new item. And
on the left, I'll choose the labels and resources category under the AX artifacts group. I'll choose resource. And
then we'll give it a name. I'll call it DB demo resource. And I'll choose add. As soon as we do that, we're going
to be prompted with a File Explorer to select a resource file. So it wants to know which resource we're going to
associate with this resource that we're adding to our project. So I'll choose an image from my local computer
and select open. And you'll see it automatically creates a resource folder for us. Here's our resource and here's
the image that references a resource. And you can see by hovering over it, we get a little preview. We can also
right click and choose open. And we'll get a full-sized preview of our image here. And we can also edit it from
here as well.

Module Review
In this module, we learned about labels in AX and how and when to use them. We reviewed the use of labels
for our fleet management scenario and then we created and used both label files and labels. Then we explored
a search capability of the label editor. Next, we reviewed best practices for using labels. And finally, we
learned about resources, and then we created and used some resources in our application.

MODULE 3 KEY TAKE AWAY


o Labels and Resources

 Labels

 Small data structures that keep all related and new labels in a central storage file

 Reference from element or artifact that point back to label file

 Label creation

 Searching

 Best Practices for Labels

 Use labels for every element/artifact

 Ensure labels contain appropriate translation of activity/item

 Use when programming for external strings

 Create label file with same name as associated model

 Resources

 Pictures

 Icons

 Visual representations
 Create and Use Resources

 Solution Explorer

 Add new item for project

 Select resource file

 Change name of resource


MODULE PRACTICE
Practice 3: Create Labels
Exercise Scenario

For the Fleet management System, there will need to be two items created. First, there will need to be a label
file to hold the labels that are included for the Fleet Management model. Second, for all of the artifacts and
elements you create, they will each need their own label.
Simon, our AX developer, will need to create a label file within our DevelopmentBasicsFMSProject so that all of
our label files will be contained with our model. Next, he will create the appropriate labels for our model.

High Level Steps


1. Open Visual Studio
2. Set Text Editor Options
3. Set Best Practice Options
4. Set Projects Options
Detailed Steps
1. In the Solution Explorer, right mouse click the DevelopmentBasicsFMSProject
2. Click Add > New Item
3. Under AX7 artifacts, select Labels and Resources
4. Select Label File
5. Enter dbFMSLabelFile in the Name field.
6. Click Add
7. The Label file wizard will display.
a. Ensure Label file ID: dbFMSLabelFile
b. click Next
c. Ensure Selected languages: en-US
d. Click Next.
e. Click Finish to create the Label File.
8. Right click dbFMSLabelFile_en-US.label.txt, click Open.
9. Click New to create a label and enter the following:
a. Label ID: dbFMS1
b. Label: Vehicle Type
c. Description: DB FMS
10. Click New to create labels for the following using Description of DB FMS for all created labels:
a. Label ID: dbFMS2 Label: Car
b. Label ID: dbFMS3 Label: Truck
c. Label ID: dbFMS4 Label: Van
d. Label ID: dbFMS5 Label: SUV
e. Label ID: dbFMS6 Label: Service Type
f. Label ID: dbFMS7 Label: Repair
g. Label ID: dbFMS8 Label: Oil Change
h. Label ID: dbFMS9 Label: Maintenance
i. Label ID: dbFMS10 Label: Registration
j. Label ID: dbFMS11 Label: Fuel Type
k. Label ID: dbFMS12 Label: Gas
l. dbLabel ID: dbFMS13 Label: Diesel
m. Label ID: dbFMS14 Label: Propane
n. Label ID: dbFMS15 Label: Natural Gas
o. Label ID: dbFMS16 Label: Electric
MODULE 3: YOUR NOTES
Module 4: Base Enumerations
Welcome to the base enumerations module. In this module, we will introduce the data types node in the
Application Explorer and discuss how and when you should create new base enumerations. In the simplest
terms, a base enumeration, or sometimes referred to as an enum, is a list of literals with an assigned value. You
will need to create base enumerations before you can begin using them in your code. Let's get started by
reviewing the objectives. The objectives for this module are to define a base enumeration, to list examples of
base enumerations, to create new base enumerations, and finally, to review best practices for base
enumerations.

Lesson 1: Fleet Management Scenario


To build upon our fleet management example that we're developing for this course, base enumerations will be
required. Let's take a look at the scenario and the details for the base enumerations that we will create. For
our fleet management scenario, we will need to build three enumerations. These will aid in tracking the vehicle
type, the service type that a vehicle receives, and the fuel type. Here are the high-level steps we're going to
cover. We will create a base enumeration. Then we will set the label property for that base enumeration. Then
we will create elements within the enumeration. And set labels on those. And finally, we will build those
elements so that we can use them in our application.

Lesson 2: Create a Base Enumeration


Now let's take a look at the process for creating a new base enumeration. The X++ language has an
enumerable type, or enum, which is a list of literals. You need to create an enum before you can use it. Enum
values are represented internally as integers. This means that they're stored in the database as a number
instead of a value. This can be useful because it saves space. The first literal has a number zero assigned to it.
The next has a number one, followed by the number two and so on. You can use enums as integers in
expressions when you write X++ code as well. Each literal or enumeration is assigned a text value through a
label property. The label property is displayed to the end user in the user interface of the application. The
system automatically does this conversion for you in the user interface so that no additional programming is
required on the forms that display to the users. So let's take a look at a few types of base enumeration
examples. The first is a no/yes enumeration. This has two associated literal values where the no value is
represented by zero and the yes value is represented by the value of one. Typically, this type of enumeration
appears as a slider in the system in the user interface. These are also referred to as the boolean primitive data
type. Another example is the sales order status enum. This enumeration is used to set the status of a sales
order automatically behind the scenes in code. You just can view the status of a sales order in the UI.
However, they cannot manually change the status of the sales order in the interface. Next is an example of the
ABC codes enumeration. ABC codes are used in several areas of the system to rate customers, vendors, or an
item for example. The user is presented with a list of options and they can select one option from the list.
Another example is a posting type. For this example, the user is displayed a variety of radio buttons. When
each radio button is selected, the user interface updates with the new values or information related to the
selected radio button. In this demonstration, we're going to add two base enumerations to our development
basics fleet management system project. To do this, we'll repeat the same process to add new elements to our
project by going to the Solution Explorer, right clicking the project name, going to add, and choosing new
item. An enum is categorized under the data types node. So from the left, we'll choose the data types group
and the first option in alphabetical order is base enum. So I'll select that and I'll give my first enum a name.
We're going to call it dbDriveType to specify the type of drive for the vehicle. And we'll choose add. I'll go
ahead and repeat that process. This time I'm going to use the shortcut keys, CTRL SHIFT A with my project
highlighted. And it will bring up that same window to allow me to add new elements to my project. Again,
we're going to choose base enum and we'll call this one DB status type. This will indicate the status of the
vehicle's maintenance. I'll choose add. And it's going to add it to my base enums folder. We can see my two
newly created enums. And now we can begin adding new elements or new options, new status types, and new
drive types to these enums. And to do that, we can right click and choose open. However, both of these are
already open here in different tabs. We have my DB status type enum and my dbDriveType enum. Let's start
on the status type enum. We can right click the root node here in the element designer and choose new
element. This represents a new choice, a new status type in this enums list. We're going to have five different
status types. So I'll keep adding new elements until I reach five. And then we'll go through and assign system
names to the enums and labels. So on the first choice, if I right click here on the node and hit rename, it's
going to allow me to add the system name for this enum. So this first status is going to be available. And then
in the properties pane on this choice, I'll set what I want the label to be. The label is what the user will see on
forms and reports. So I'll keep the label as available. That's a very user friendly status. The next option is
going to be in maintenance. Now, I can right click and hit rename. And I'll type in maintenance. Now, we
notice I can't use spaces here because this is just a system naming convention for in choice. And the label, I'm
free to add spaces and type it as I please. OK. We'll continue on to the third choice. This time I'm going to use
a shortcut key. I'll press F2 with this choice highlighted as a quick way to rename an element. This option will
be in repair. I'll go down to my label property and type in repair. For the fourth choice, we'll use in detail. And
again, I want to mirror that on my label with a space. And for the final choice, I'll hit F2 to rename it, and it's
going to be out of service. And for my label, type out of service with spaces. OK. So now, what we can see, if I
click the very first option on the list, which is the status of available, the enum value property is zero. It begins
at zero and then it increments from there. So I have five choices which are represented by zero through 4. As I
click the different element choices, we can see the enum value increases. And that continues through the list
until I reach the last one. And remember, this numerical value is what's stored in the database. OK. So now
that we've finished that element, let's go over to the dbDriveType enum and we're going to have four different
drive types. So again, I'll right click the root node of my enum. And choose new element until I get to four
choices. And we're going to have four four-wheel drive, all-wheel drive, rear-wheel drive, and front-wheel
drive. So, I'll specify those values as FWD for front-wheel drive, and the label, I can spell it out fully but FWD is
a common acronym for front-wheel drive vehicles. So I think my users would appreciate that. We'll continue
on the list. This one will be RWD for rear-wheel drive. I'll have my label be the same. The next one will be
AWD for all-wheel drive. And the final one, we'll call it four-wheel drive. And for my label, I'll use the number
four instead as 4WD to indicate that vehicle has four-wheel drive. OK. So now, these elements are created.
I've added my choices. They have enum values and labels. So I can right click each tab up here and save to
save that individual enum. And make sure all my changes are being saved to my project. Alternatively, we can
click this icon here with two disks to save all of the elements. The shortcut key for that is CTRL shift S. OK. So
now, we just want to go ahead and make sure we do a build on our project to make sure there's no errors and
everything is looking good. I'll right click the project and choose build. We can see in the output down here, it
updates with the status of our build. It will notify us when it's complete, and then we can continue developing
and adding new elements to our project.

Lesson 3: Best Practices


There are many considerations you should keep in mind when deciding to use a base enumeration. Let's
review some of the guidelines that should be followed. We should define and use enums when a field or
variable can have a limited fixed number of predefined outcomes. If there might be an unlimited number of
user-defined outcomes, it's recommended to use a to-be-related-to table instead. If you want to make an
enum a mandatory field on a table, make the first outcome with the value zero as none and set the label
property to not selected. Most enums can be regarded as specialized types and should be used as they are.
Some enums, like no, yes, and table group all, can be regarded as more general types. They can be specialized
by using extended data types. If you want a default value for your base enumeration, the value of the zero
must be used. Otherwise, you need to add code to the appropriate table where the defaulting must occur. If
you are going to manually delete any enumeration, modify an existing enumeration or its values, you should
consider the data related to that enumeration. You will need to determine whether it has been used in
persistent storage and existing tables and if old data must be taken into account. Let's review a few more best
practices for working with enums and constants. Always let the constant be an enumerator. Never use
numeric constants instead of enums. Never use other constants such as other enum types instead of enums.
Do not make boolean tests on enum fields except where the zero or false value is clearly the one with the false
outcome. You should never use relational operators on enums. You should also never compare or assign to
enums of different types. And finally, do not expect the enumerators to have a numeric value in the range of
zero which is the number of enumerators minus one.

Module Overview
Thank you for joining me in the base enumerations module. In this module, we introduced the data types
node and the Application Explorer and discussed how and when you should create new base enumerations.
We also reviewed a few examples of base enumerations that are used with AX and I showed you how to create
new base enums. Finally, we reviewed the best practices and considerations for using base enumerations with
your projects.

MODULE 4 KEY TAKE AWAY


o Base Enumerations

 Create a Base Enumeration

 X++ enumerable type (enum)

 List of literals

 Enum must be created in Application explorer

 Represented internally as integers

 Stored in database as number

 Saves space

 Can use enums as integers in expressions writing X++

 Assigned a text value through label property

 Label property is displayed to end user in GUI


 System automatically converts

 Best Practices

 Consider:

 Length

 If it should be mandatory

 If it is a special type

 If you want a default value

 Data if deleting an enumeration or value

 Always let constant be enumerator

 Never use numeric constants instead of enums

 Never use other constants instead of enums

 Do not make Boolean tests on enum fields

 Never use relational operators on enums

 Never compare or assign to enums of different types

 Do not expect the enumerators to have a numeric value in the range of 0

MODULE PRACTICE
Practice 4: Create Base Enumerations
Scenario

For our fleet management scenario, we will need to build three enumerations. These will aid in tracking the vehicle type,
service type, and the fuel type.

Simon, our AX developer, will need to create three base enumerations needed for our model.

-dbfmServiceType
None
Registration
OilChange
Maintenance
Repair
-dbfmVehicleType
Car
Truck
Van
SUV
-dbfmFuelType
Gas
Diesel
Propane
Natural Gas
Electric

High Level Steps


1. Create a base enumeration
2. Set the label
3. Create the Elements
4. Set the labels on the elements
5. Create the remaining enumerations
6. Build
Detailed Steps
1. In the Solution Explorer, right click the DevelopmentBasicsFMSProject
2. Click Add > New Item
3. Under AX7 Artifacts, click Data Types
4. Select Base Enum
5. Enter dbfmServiceType in the Name field.
6. Click Add
7. Right click the newly create dbfmServiceType (usr) [DevelopmentBasicsFMS] in the middle
white pane and click Properties.
8. Enter Service Type in the Label field under the Properties section on the lower right side of
the screen.
9. Right click the newly created dbfmServiceType (usr) [DevelopmentBasicsFMS] in the
middle white pane and click New Element.
a. Right click on EnumValue1 and Click Rename
b. Enter None in the Name field and click Enter.
c. Enter None into the Label field.
10. Right click the newly created dbfmServiceType (usr) [DevelopmentBasicsFMS] in the
middle white pane and click New Element. Repeat steps 9a-c to create the following
elements:
a. Name: Registration Label: Registration
b. Name: OilChange Label: OilChange
c. Name: Maintenance Label: Maintenance
d. Name: Repair Label: Repair
11. In the Solution Explorer, right click the DevelopmentBasicsFMSProject
12. Click Add > New Item
13. Under AX7 Artifacts, click Data Types
14. Select Base Enum
15. Enter dbfmVehicleType in the Name field.
16. Click Add
17. Right click the newly create dbfmVehicleType (usr) [DevelopmentBasicsFMS] in the middle
white pane and click Properties.
18. Enter Vehicle Type in the Label field under the Properties section on the lower right side of
the screen.
19. Right click the newly created dbfmVehicleType (usr) [DevelopmentBasicsFMS] in the
middle white pane and click New Element. Repeat steps 9a-c to create the following
elements:
a. Name: Car Label: Car
b. Name: Truck Label: Truck
c. Name: Van Label: Van
d. Name: SUV Label: SUV
20. In the Solution Explorer, right click the DevelopmentBasicsFMSProject
21. Click Add > New Item
22. Under AX7 Artifacts, click Data Types
23. Select Base Enum
24. Enter dbfmFuelType in the Name field.
25. Click Add
26. Right click the newly create dbfmFuelType (usr) [DevelopmentBasicsFMS] in the middle
white pane and click Properties.
27. Enter Fuel Type in the Label field under the Properties section on the lower right side of the
screen.
28. Right click the newly created dbfmFuelType (usr) [DevelopmentBasicsFMS] in the middle
white pane and click New Element. Repeat steps 9a-c to create the following elements:
a. Name: Gas Label: Gas
b. Name: Diesel Label: Diesel
c. Name: Propane Label: Propane
d. Name: NaturalGas Label: NaturalGas
e. Name: Electric Label: Electric
29. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
30. Click Build Solution (or use Ctrl+Shift+B)
31. Review the Output screen to review the process. Should say “Dynamics AX7 build
completed”.
MODULE 4: YOUR NOTES
Module 5: Extended Data Types
Welcome to the extended data types module. X++ data types are divided into primitive data types and
composite data types. You can also create extended data types and base enums which build on the primitive
data types. These can be created only by adding these types of elements to your projects. They cannot be
created in code as a language construct. Let's get started by reviewing the objectives. The objectives for this
module are to review the primitive data types within AX, to create new extended data types that we'll use in
our fleet management scenario, and to describe the best practices for data types.

Lesson 1: Fleet Management Scenario


In this module, we will create extended data types from the primitive types that we will then use in our fleet
management example. The basic flow is to determine the primitive data type that we need that will create an
extended data type from that, we will set the label value that will be displayed for our users and the UI, we will
configure any additional properties on the extended data type element, and then we will build the element.
The scenario we're going to use is as follows. The business users at Contoso have identified a variety of
information that needs to be tracked in the new system as part of the fleet management system. Simon, the
system's developer at Contoso, has reviewed the list and categorized each piece of information into the type of
data that will be stored. And now he needs to find existing extended data types to use for the fleet
management solution. Extended data types are commonly abbreviated and referred to as EDTs. The following
tables represent a list of EDTs that Simon is considering creating for the fleet management system. We can see
an EDT of type date is going to be used to represent which year the vehicle was made. An EDT of type string
could represent the VIN number, or the vehicle identification number, for a particular vehicle.

Lesson 2: Primitive Data Types


The basic set of primitive data types in AX map to underlying data types that exist in the physical database.
These primitive data types can be expanded to create extended data types which are reusable data types that
have a specific definition and specific properties set. Let's take a look at the primitive data types available in
AX. The data type, any type, can be used as a placeholder for any data type. Booleans are a data type that can
only contain the values true and false. These are commonly used as a slag or a switch in the system. The data
type of dates contain a day, month, and year value. The data type of enums we discussed in the last module
are an abbreviation for enumerated text, a set of literals. GUIDs are globally unique identifiers. The data type
integers represent a number without a decimal point. This is a whole number for example of ten. To declare
an integer in code, we use the keyword int, or I-N-T. A data type of real is also a numerical data type that
includes a decimal point. These can also be referred to as decimals. The data type of string represents a
certain number of characters. To declare a string in code, we use the keyword STR. A string can be any kind of
sentence or word. The time of day data type contains hours, minutes, and seconds. To declare a time, we use
the system type time of day. And finally, we have the UTC date and time. This contains the year, month, day,
hour, minute, and second.

Lesson 3: Create an EDT


Now that we went over some of the primitive data types, let's review the process for creating a new extended
data type. An EDT is a primitive data type or container with a supplementary name and some additional
properties set. For example, we can create an EDT called name based on the primitive data type of string.
Thereafter, we can use that new EDT in variable and field declarations in the development environment. Let's
look at some of the benefits of EDTs. The first is that code is easier to read because variables have a
meaningful data type. For example, name instead of string. Properties of EDTs can be inherited. This means
the properties we set for an EDT can be used by all instances of that type which promotes consistency and also
reduces work. For example, account numbers are based on the account num data type and they have the same
properties throughout the system. You can create hierarchies of EDTs which inherit the properties that are
appropriate from the parent down to the child. For example, the item code data type is used as a basis for the
markup item code and the price disk item code data types. Most fields in AX tables are based on extended
data types. After its created, it can be reused as many times as is needed in the application. In this
demonstration, let's go ahead and create some EDTs or extended data types to use for our fleet management
system. We'll begin by adding new EDTs to our project. So we'll right click the project, we'll go to add and
we'll choose new item. From the left pane here, we are going to go into the data types group and we'll see we
have all these different types of EDTs that are based on different primitive data types. So in the first example,
we'll do an EDT of type string and we'll call it DB VIN to represent a vehicle identification number. And we'll
choose add. This will create an EDT string type folder here with our EDT inside of it. So we also have our EDT
element designer open and we can go set some properties on this EDT. So in the label, let's go ahead and type
in VIN and we want to change the string size probably to be a little larger than ten because the vehicle
identification numbers can be quite long. So let's go ahead and just change this to 25. And we'll set our help
text to a simple sentence to describe what this is. So I typed a sentence that says this represents the vehicle
identification number. OK. So we can right click this element and save it. And then we'll continue adding new
EDTs. So we'll repeat the process by right clicking our project, going to add, and new item. This time, let's
create an EDT of type date and we'll use this as a field to represent the year that a vehicle was made. So we'll
call this DB year. And we'll choose add. It makes a new folder. This is an EDT of type date. We can see our
element in there and we can go ahead and set properties on that again. Let's continue making our -- the rest
of our EDTs, first. So we'll repeat again. And this time we'll choose an EDT of type integer. This will represent
a number, a whole number. And we'll call this one DB num of doors. So this integer is going to represent the
number of doors a particular vehicle has. OK. So there's our folder created with our element. I'll highlight my
project again. This time I'm going to press CTRL SHIFT A for the shortcut key. That allows me to add new
elements to the project. We'll continue adding different EDT types and this time, let's use an EDT of type real
which is a decimal number. And we'll call this DB fuel capacity. So we can have a fuel tank that is 12.5 gallons
for example. So we'll need a real or a decimal type to represent that. So our folder is created. That's great.
We'll close that and continue adding. I'm going to use the CTRL shift A shortcut again. And now we can
choose to add another EDT type. And this time, let's use an EDT of type enum. So we discussed base enums in
the last module. They represent a list of literals. So we'll call this DB fuel type code. So there's a finite list of
fuel type codes that refer to different fuel types. And we'll add that. So now, we have a list of different folders
that represent our different EDT types. It's nice and organized. We can go in there and then set properties on
our individual EDTs. So now that I've set these properties on this DB VIN EDT, I can reuse this on any table
anywhere else in the system and it's going to maintain these properties that I've set, which is the label and the
string size. So any properties that you set on it are going to be saved in that EDT and they can be reused. We
can also extend this type which will inherit all of these properties and then we can change additional
properties. So it's almost like a complete copy with some minor changes if that's something you would require.
So one more thing we can do with EDTs is have them extend from another EDT or inherit the properties. So for
example, I'm going to go to our EDT dates folder where I created this DB year EDT which represents the year a
vehicle was made. And I can go down to find -- well, first of all, we have to right click and choose open. So we
have it in our element designer. And then we can go through the properties and set them. OK. So I can go
through here and have this EDT extend from another EDT. The extends properties located in the data group,
so once I put my cursor here, it brings up this drop-down arrow where I can click and choose another EDT in
the system that I want though one to inherit the properties from. We can also type it in if we know the name
of it off the top of our head. I'm going to try to find one called trans date which is a commonly used data EDT
to represent different types of dates. OK. So now that I've chosen that as my extended form, it will inherit the
properties from that trans date system EDT.

Lesson 4: Best Practices


It's important to follow best practices when creating new extended data types. Let's consider the following
guidelines when developing new solutions in AX. The basic rules for using extended data types are as follows.
You should use an EDT whenever possible. An EDT should be created for each atomic entity in a situation that
your application is modeling. It should pass the is a test, which means the hierarchies that you create among
extended data types should be able to pass this test which implies that an extended data type should be a
member of a parent data type. For example, the subitem ID is a item ID but the subitem ID is not a class name.
You should only create subtypes when they are needed. If you want to add a field to a table or to a dialog, do
not choose a type that is too general. Instead, create the type from the beginning and reuse it everywhere
else. Also, you do not want to directly use the system data type for recID or table ID. It's recommended to use
the extended data type ref recID or an extended data type that is derived from ref recID. Now let's review
some best practices for setting extended data type properties. The first one is to follow naming standards.
Next, we want to use labels for all user interface text. This provide's clarity for our end users. The help text
property should not be the same as the label. It should be a little more informative. It's recommended to
leave a display length and style as auto when possible. You also want to specify the enum type for all enums.

Module Review
Thanks for joining me in the extended data types module. We took a look at each of the primitive types that
are used in AX and looked at several examples of creating new extended data types and setting properties
specific to those types. Then we discussed the best practices for using extended data types in your solutions.

MODULE 5 KEY TAKE AWAY


o Extended Data Types

 Primitive Data Types

 Map to underlying data types that exist in physical database

 Can be expanded to create extended data types

 Types

 Anytype

o Placeholder for any data type

 Booleans

o Can only contain values false and true


 Dates

o Contains day, month, and year

 Enums

o An abbreviation for enumerated text – set of literals

 GUIDs

o Globally unique identifier

 Integers

o Number without decimal point

o To declare use keyword int

 Real

o Numbers with decimal point

o AKA decimals

 String

o Number of characters

o To declare use keyword str

 TimeOfDay

o Contains hours, minutes, seconds

o To declare use system type timeOfDay

 UTCDateTime

o Contains year, month, day, hour, minute, second

 Create EDTs

 Benefits of EDTs

 Code is easier to read

 Properties are inherited


 Provide consistency

 Reduce work

 Best Practices

 Use EDTs whenever possible

 Create one for each atomic entity

 Pass the “is a” test

 Only create subtypes when they are needed

 Do not directly use system data type for recID or tableID

 Following naming standards

 Use labels for all user interface text

 Help text should not be same as label

 Leave display length and style as Auto when possible

 Specify enum type for all enums

MODULE PRACTICE
Practice 5: Create Extended Data Types (EDTs)
Scenario

The business users at Contoso have identified a variety of information that needs to be tracked in the new
system as a part of the fleet management system.

Simon, the Systems Developer at Contoso, has reviewed the list and categorized each piece of information into
the type of data that will be stored, and now needs to create or find existing EDTs to use for the Fleet
Management solution.

Isaac creates a new page, defines the variables and the layout of the page, and then adds an action that
calculates a relational expression.

High Level Steps


1. Create an Extended Data type
2. Set the label
3. Configure properties
4. Create the remaining extended data types
5. Build
Detailed Steps
1. In the Solution Explorer, right click on DevelopmentBasicsFMSProject.
32. Click Add > New Item
33. Click Data Types
34. Click EDT Date (this will change based on type)
35. Enter dbfmYear in the Name Field.
36. Click Add
37. Right click the newly created dbfmYear (usr) [DevelopmentBasicsFMS] in the middle white pane and
click Properties.
38. Enter Year in the label field under the Properties section.
39. Set the Date Year field to Digits4
40. Repeat steps 1-9 for remaining EDTs in step 11. Please note that properties change based on type of
EDT.
41. The list of EDTs. TYPE is in Bold, then name, then label, then special properties:
Data Type: EDT Date
Name: dbfmInspectDate
Label: Inspect date
Special Properties: Extends = TransDate
EDT Date
dbfmServiceStartDate
Service start date
Extends = TransDate
EDT Date
dbfmServiceEndDate
Service end date
Extends = TransDate
EDT Enum
dbfmThirdRowCode
Third row
Extends = NoYesID
Enum Type = NoYes
EDT Enum
dbfmFuelTypeCode
Fuel type
EnumType = dbfmFuelType
EDT Enum
dbfmVehicleTypeCode
Vehicle type
EnumType = dbfmVehicleType
EDT Enum
dbfmServiceTypeCode
Service type
EnumType = dbfmServiceType
EDT Integer
dbfmGrossVehicleWeight
Gross Vehicle Weight (GVW)
EDT Integer
dbfmNumberOfDoors
Number of doors
EDT Integer
dbfmSeatingCapacity
Seating capacity
 
EDT Integer
dbfmMileage
Mileage
AllowNegative = No
EDT Integer
dbfmVehicleID
Vehicle ID
EDT Real
dbfmFuelLevel
Fuel level
EDT String
dbfmMake
Make
EDT String
dbfmModel
Model
EDT String
dbfmNote
Note
String Size = (Memo)
EDT String
dbfmVIN
Vehicle Identification Number (VIN)
String Size = 18
String
dbfmEngineDescription
Engine description
42. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
43. Click Build (or use Ctrl+Shift+B)
44. Review the Output screen to review the process. Should say “Dynamics AX7 build completed”.
MODULE 5: YOUR NOTES
Module 6: Tables
Hello, and thank you for joining me in the tables module. We will discuss some of the key properties and
features of tables and how they work in the Visual Studio development environment. Let's get started by
reviewing the objectives. The objectives for this module are to create a table to store information, to add data
types such as fields, EDTs, and base enumerations to the table, to extend a table using the concept of
inheritance, to set key properties for a table, to create a temporary table, to create a query that uses a table as
a data source, and finally, to review the best practices for tables.

Lesson 1: Fleet Management Scenario


Tables will be required to build upon our fleet management example for this course. We will use the base
enumerations and extended data types that we created in the earlier modules to create our tables. Let's review
the scenario. Two tables have been identified for the new fleet management module for Contoso. One table
will store basic vehicle information and a second table will store vehicle maintenance information. The table for
the vehicles will need to track the following information. Fuel level, fuel type, gross vehicle weight, inspection
date, vehicle make, mileage, vehicle model, notes, number of doors, seating capacity, third-row seating, a
unique vehicle ID, vehicle type, VIN, and year. The table for maintenance, we need to track the following
information. Service type, engine description, service start and end dates, and the vehicle ID. The scenario is as
follows. Simon, the developer for Contoso, needs to create tables to store information about various types of
vehicles in the fleet. Add two tables to the project to achieve this goal. The flow will be to create a table to
store key information, to create labels for that table, to set properties on the table, and then to add our EDTs or
fields to the table, and finally, to build the table.

Lesson 2: Create a Table


In this lesson, we'll review how to create a table in Visual Studio. The main purpose of tables is to store data
such as company transactions, inventory, and journals. Tables contain rows and columns. These rows are
called records. You can think of a table like a spreadsheet. Collectively, they're stored together in a database
and work together to deliver data to the end user and outputs such as forms and reports. Tables can also
contain metadata which is not business or transactional data, but rather description data such as systems
setting. The following screen shot shows the element designer view for a table. Here, we have a table called
table one and below it, all the components that make up the table. The first component is known as fields.
Fields make up data in a table. For example, we can have a field called customer name or customer address.
Fields can also be base enumerations or extended data types. Field groups are logical groupings of physical
database fields. Field groups can be used on forms and reports so that when a modification is made to the
field group, related objects are automatically updated to reflect the new content of that group. Indexes are a
way to speed up retrieval of data from a table and relations define how this table relates to records in other
tables. The delete actions node will not be used. Delete actions node will be used for upgrading from previous
versions. However, delete actions on new elements are set within the relationship properties. We'll look at
these pieces in the coming modules. Methods are pieces of code that are added to a table that can be
executed when certain events or changes in the data occur. For example, there can be a method to insert or
find data in a table. Events store code to be executed when something happens in the table. The state
machine feature enables workflow events to be bound to state transitions in the underlying entity state
machine. This enables you to perform state transitions within a workflow without writing any additional code.
With a map, you associate a map field in one or more tables. This enables you to use the same field name to
access fields with different names and different tables. For example, in two separate address tables, one can
refer to the zip code field as zip code and the other table may call it postal code. Now we're going to add two
tables to our project to store information for our fleet management system. To add a table, we repeat the
same process that we do to add any element to our project. So we right click, we choose add, and we choose
new item. In the left pane under the AX artifacts, we want to choose data model. This is where the tables
reside. So we'll select table as our element type. We'll call this one dbVehicle. This will store all of the main
information for the vehicles in our fleet. So once I choose add, it opens up in the element designer. It also
adds a folder here where my future tables will continue to be added. To create a second table, we can certainly
repeat that process. We can also highlight this table and copy and paste it. So I'll right click and choose copy.
I'll choose my tables folder, and I'll right click and choose paste. It's going to simply append the name copy to
the original table. I can highlight this and press F2. So I can rename it to my liking. I'll call this one
dbMaintenance. And this table will store all of the maintenance information for our vehicles. So the first
property I'm going to set is the label property. So I'll need to right click my table element and choose open to
make sure that it's open in the designer and then I am allowed to begin editing the properties on that element.
So for the label, for the dbVehicle table, we'll simply call it vehicles. I'll right click and open my maintenance
table. And I'll go ahead and change the label on this one to simply be maintenance.

Lesson 3: Adding Data Types


In this lesson, we will add data types to the table so that we can store information. Data types include fields,
base enums, and extended data types. We will use some of the previously created extended data types along
with some new fields to build our tables. So now that we've added two tables to our project, and we've set the
label property on them, we can begin to add elements, data types, and fields to our table. So currently, I have
the dbMaintenance table opened. Now, I can begin adding fields by highlighting the field node and right
clicking, choosing new, and then selecting a data type. We can also drag and drop EDTs, enums and fields
from our project pane on to the table. So for the dbMaintenance table, I'm going to add this enumeration of
service type. I can simply drag it over to the fields node and it will populate. Now, I've added some new fields
here simply for the purpose of having more information for our tables. So we walk through the process of
creating all these different EDT types and enumerations. I've simply added a few mores in here just to make
our solution a little more robust. So for the maintenance table, we're also going to add the string for vehicle
ID. This will be our internal identification number for our vehicles. So we want this to be on both tables
actually so we can create a relationship in the future on that field. For the maintenance table, we also want to
have our service start and end dates and those are in our EDT date folder. So I will click the begin date, I'll
press CTRL so I can select the additional service end date, and then I can drag both of them on to the fields for
my maintenance table. OK. And next I want to add the vehicle type enumeration so that I know which type of
vehicle is being serviced in my maintenance table. And I'll drag that out there. So those are the fields we're
going to add for the maintenance table. So I'll click over to my dbVehicle table tab and I will add some fields
to this. For the dbVehicle, we're going to have a lot of general information about vehicles. So if I go to my EDT
strings folder, we have make and model, vehicle ID and VIN number. And again, I'm holding CTRL so I can
select multiple elements so I can drag them on to my fields node. OK. Now let's go to the EDT integers folder.
Here we have an integer type of number of doors. I'll drag that onto my vehicle table. I will also go to the
enumerations and drag the drive type field. Then within my dates, I will choose my DB year to indicate which
year this vehicle was manufactured. And then we will choose the vehicle type enumeration and drag that out
there. OK. So now I have a handful of fields on both of my tables. And we can begin adding data to the table
now. So let's make sure we choose the double disk icon here to save all, which will save the changes that I've
just implemented on both of my tables. We mentioned that field groups are logical groupings of physical
database fields. AX uses field groups to cluster fields into logical collections so that they may be used with
other AX objects such as forms and reports. An example of a field group is the address group located in the
address field group on the cust table. Some common uses for field groups not only include to organize logical
groupings of fields and data but also to help dynamically update some objects. For example, if a modification
is made to a field group, related objects are automatically updated to reflect the new content of the group. So
if we have a form that has the address field group on it, and then we modify the address field group on a table
to include a new field, for example, PO Box or address line two, the form with that field group will automatically
update to reflect those changes you made in the field group on the table. So adding new fields to a field
group can be a powerful technique for updating forms. We will discuss best practice checks for using field
groups in the best practices lesson of this module. OK. So we have our two newly created tables with the
fields and data types added to them that we have just done in the previous lesson and I have the
dbMaintenance and the dbVehicle table opened up in the element designer so I can go ahead and begin
modifying both of them. So with the dbVehicle table selected and opened, I want to expand my fields node
just to take a quick look at the fields that we've added here. So we have handful of fields to use in this table
and now we want to create a field group. So if I highlight the fields group node, I'll expand it. And here we can
see some default field groups that are created each time you create a new table. These are created by default.
If I right click the fields group node, I can choose new group to create a custom field group. With the field
group one highlighted, I'll press F2 so I can name it to my liking. And I'll call this vehicle description. OK. Now,
we can add fields to this field group in a couple of ways. The easiest way is to go up to our fields here and
drag them into it. So I want to choose DB make. I'll hold CTRL so I can select an additional item which would
be DB model and DB year. And I'll go ahead and just drag these down into my newly created vehicle
description field group and they will appear there. Now, another way to add fields to the field group is to
simply highlight the field group, right click it, and choose new field. It will create this blank node here, and
then in the properties pane, we can choose the data field drop down will allow us to choose a field from our
table. OK. So we see some system fields in here like recID, and then we see the fields that we've created there.
So we can choose any of those fields to add to the field group. For this purpose, I just want these here so I'll
go ahead and right click this blank field and choose delete. OK. So we have our vehicle description field
group. It's ready for use and we'll see how that can be beneficial in later lessons when we begin to create
forms off of these tables. OK. So I'll go ahead and choose the double disk to save all of my changes here. And
then I would like to perform a database sync. Since we've been creating these different elements and tables,
we want to make sure that what we're creating is in sync with the database or added to the database on the
back end. So an easy way to do that, we can right click our project and choose properties and we can have
synchronized database and build set to true. This way, every time we perform a build it will sync our elements
with the database. So with my project selected, I'll right click and I'll choose build. Again, we have an output
here. It's walking us through the build steps and we can see that the database sync has completed.

Lesson 4: Key Properties


In this lesson, we'll explore some of the important properties that can be set on tables. Let's take a look at
some key table properties. The first one is table type. This determines if it's a regular table stored in the
database or if it's a temporary table. We'll discuss the different types of temporary tables later in this module.
The name and label properties are used to determine the system name and the user-friendly name. The
primary index properties specifies which field to use for the primary index. Only a unique index can be
selected. This property is used for database optimization purposes. Indexes are set on a field or fields from the
table. A cluster index is to be set on the table and it determines how data is organized within the table. A
cluster index should never be left blank. We will look at indexes more in depth in the module on table indexes.
A configuration key property should be set in most tables. This ensures that the table is removed when the key
is disabled. Configuration keys are a way to allow system administrators to enable or disable certain parts of
an application. The support inheritance property can be set to yes or no. Setting this option to yes indicates
that a table can be extended or inherited. Then, the extends property chooses which base table that the
selected table will inherit or extend from. We will also discuss this concept later in this module.

Lesson 5: Table Inheritance


Now let's take a look at the concept of table inheritance in Dynamics AX. When we extend a table, we're using
the concept of table inheritance. A table can be extended from or derived from another table. Each table has a
support inheritance property and the extends property, which together, control table inheritance. We can set
the support inheritance to yes and then use the extends property to choose which base table in the system we
want to extend with the current table. In the terminology for table inheritance, we say that the derived table
extends its base table. The purpose of table inheritance is to reduce work by allowing the sharing of attributes
and fields from another table. Let's check out an example of how inheritance works. Let's consider the
following three tables. In this example, the FMVehicle table is what we call the base table. So FMCars and
FMTruck inherit fields or properties from this table. There's no need to have common fields like VIN number,
year, or vehicle make in all of these tables when the FMCars table and the FMTruck table can simply both
inherit these. Now, you'll notice in the FMCars table, we have fields that are specific or independent to a car
such as the boolean field sedan which would be: Is it a sedan? Yes or no. Is it a coupe? Yes or no. The
FMTruck table has a field called hauling capacity which is specific to trucks. So independently, they have fields
that are important or specific to them and they can inherit other common fields from another table so that
they don't have to be recreated and re-added. In order to use the concept of table inheritance in our example,
I'm going to create an additional table. So I'll go to my project, I'll right click, and I'll choose add new item.
Again, under the data model group, I'm going to choose table, and I'll call this one DB cars. So this table will
be specific to vehicle types of cars. So this table is going to extend or inherit from the main dbVehicle table.
So in order to set this up, what we first have to do is open up these tables in the element designer. So I'm
going to go to my dbVehicle table and if I scroll down to the bottom in the properties window, there's a group
called super type, subtype and a property called support inheritance. I need to change this to yes on both the
base table, which is the dbVehicle table, and the derived table or the child table that is inheriting the traits. So
I'll flip that to yes on dbVehicle. I'll save it. I'll go to my newly created DB cars table. And I'll go ahead and flip
that same support inheritance property DS. And on the derived table, there's another property called extends
that we need to set. This tells it which table it's going to derive from. So I'll simply type in my dbVehicle table,
and now it knows to inherit the traits or the fields from that table. So I'll go ahead and save this table. Now,
you'll notice if I right click on my DB cars child table here, there's an option in the context menu to go table
dbVehicle, so it knows that it's now an inheritance relationship. OK. Another thing we can do is if I right click
on either the vehicle or the cars table, there's an option called view hierarchy. And this will show us a graphical
view of the inheritance that's set up on this table. So it opens up a DGML file and we can see it has DB cars
pointing to the base table of dbVehicle. And if we were to set up additional tables that inherit from this
dbVehicle table, for example a truck table or a van table, we would see those appear here in this diagram as
you continue to build out those relationships. OK. So it's important to note that the DB cars table right now
has no fields. So for example, I'm going to add a couple fields real quick. So I have a field I created called DB
coupe and one called DB sedan, and these simply are no/yeses. So is this car a coupe? Is this car a sedan?
Now, I can add those fields to the car table, and those fields are accessible from this table, but idea with
inheritance is now my car's table can access the fields from the dbVehicle table. So my dbVehicle table is the
main base table and that contains all those fields we added like VIN number, year, and vehicle make. So I don't
need to read those on to my car table. They automatically inherit those. So for example, if I were to create
some code, I could reference those fields from my cars table in the code. And then if I were to insert a record
into the cars table that had a field from the vehicle table, I could do that as well, and the code would know to
insert the information into the correct table. So if I was updating a field like vehicle make on the cars table, it
would insert that here into my vehicles table as well.

Lesson 6: Temporary Tables


In this lesson we will review how to create and use the different types of temporary tables. There are two main
types of temporary tables. An inMemory temporary table and a tempDB temporary table. These are controlled
using the table type property on the properties node of a table. Common uses for temporary tables include
reporting. A tempDB table is created in the database only when it is in use or instantiated by a particular
process. It is then dropped when it's no longer needed. TempDB tables are often used to store data from
reports as they may be joined with other tables. An inMemory table is instantiated when the first record is
inserted and continues to exist until the buffer variable controller goes out of scope. InMemory tables are held
inMemory until the size reaches 128 kilobytes. Once this threshold is exceeded, it begins to allocate the
additional space between the RAM and disk. This can cause performance to suffer. Because of this, it's
recommended to use a tempDB table to handle larger data sets. A general rule of thumb is to use a tempDB
table if you anticipate your data set or report will exceed 5000 rows or records. The data in these temporary
tables is controlled through code and cannot be seen by using the temp table browser feature. When you
create a temporary table, it's always a best practice to prefix the name with TMP so that it can be easily
recognized as a temporary table.

Lesson 7: Queries
In this lesson, we'll talk about the creation, use, and benefits of queries. A query element can be designed as a
modular business object. Queries can contain one or more tables as a data source. These tables may be
nested within each other if they are related like in the screen shot. We have a FMT customer table and an FMT
customer group table nested and related to that table below it. Queries are flexible because they're easily
changed and can be modified at runtime. For example, a report that uses a query as a data source can have
parameters set dynamically at runtime before the report is executed. You can also change other options like
ordering by certain fields at runtime as well. A query object can then be reused as a data source to provide
data for other forms and reports in the system. So now let's go ahead and add a query element to our project.
Now, we discussed a bit about queries and how they are very flexible and very reusable. They're a good data
source that we can reuse for forms and reports. And they also allow us to specify details at runtime before we
execute them. So if we right click our project again, we can choose add and we'll add new item. And queries
live here in the data model element type group just above table. So we'll select it and we'll type a name for our
query. We'll call it dbVehicle query. I want this query to be based off my vehicle table. I'll add it. We have our
new folder here with the query element itself and it's opened here in the element designer. So let's go ahead
first of all and give it a title. So we'll set this property. We'll just call it vehicles. OK. Now, the data source's
node specifies which table or tables we're going to have as a data source for this query. I could go to my
project and open up my tables folder and simply drag a table to the data source's node. So now, I have my
dbVehicle table as my data source. If I expand the data source itself, we can see there's fields which specify
what fields we want to include from that table in this query. By default, none are added. We can right click and
choose new and we can choose a field and then this will allow us to specify which table in the query that we
want the table to come from and then which field that we're going to add. So I can see here in my drop down
that I'm going to have different options for choosing the tables and fields. So here's all the fields I can add. I
can add them one by one to choose only a subset of field that I want in this query. Maybe I have a specific
purpose for this query that's only going to use a couple fields, so we can go ahead and manually add fields to
the query simply by right clicking and choosing new field. We also have the option to have some of these
aggregate features in a query if we want to sum up a field from our table. We can also have that feature. So
I'm going to delete this manual field real quick. And there's another option we can use for queries which is
called the dynamic fields. So if I choose my dbVehicle data source table, and I go to the properties, there's an
option here called dynamic fields. And by default, it's unselected. We need to set this to yes or no. If I set it to
yes, it dynamically adds all of the fields, including system fields, from my dbVehicle table into the data source
for my query. The benefit of this is if, in the future, I decide to add more fields to my vehicle table, they will
dynamically update here in my query that has that table as a data source. So it's important to note if that
feature would suit you. OK. So we can go ahead and close up these tabs here and we'll save our query. OK.
So now I'm going to add one more query to this project. So I'll right click my project again and repeat the
steps by going to add, new item, choosing query from the data model artifact group, and give it a name. We'll
call this one dbVehicleMaintenance. And it goes ahead and adds a new query here to my simple queries folder
and it opens in the element designer by default. So what I want to do with this query is, first of all, add a data
source. Now, on my last vehicle query, I added the vehicle table as the single and only data source. For this
one, I want to add both the dbVehicle and the dbMaintenance table. To do that, I'll first click my dbVehicle
table and drag it to the data source's node. When I expand this data source, I have some different options
here, and we can see another data sources node exists. This gives me the option to create a nested data
source and that's what I want to do for my dbMaintenance table. I want it to be a nested data source within
my dbVehicle table. So I'll drag that out to this data source's node. And we can see if I continue to expand this
nested data source, there are options to continually add more and more data sources within data sources. So
when I create this nested data source within my dbVehicle main data source, I need to specify a relationship
between them so that these data sources know how they are related and they can communicate that way. So
I'll right click my relations node in my nested data source, and choose new relation. I'll go to the properties
pane over here and set a few properties to set up the relation. Firstly, I'll go to the field property and use the
drop down to specify which field in my dbMaintenance nested data source I want to use in the relation. And
that's going to be the vehicle ID field. For joined data source, if I click the drop down, we'll notice we only have
the dbVehicle table as an option because that is the only other data source in this query and it's the parent
data source for this nested data source. So I'll choose that, and then in the related field property, I'll choose
which field from this joined data source parent that I want to use in the relation. In other words, which field in
the dbVehicle table I'm going to relate to the vehicle ID field and the maintenance table. And that field is the
same, the same name in both places, dbVehicleID. So once I finish choosing those properties, we can see it
populates here this relation, the details. DbVehicletable.dbvehicleID field equals the dbMaintenance table and
the dbVehicleID field. So that's exactly what I wanted. The last thing I'll do is just give this joined relation a
name, and I'll just call it the vehicle ID relation. And I can go ahead and save this query. Some last things to
note about queries are these different options here. We already discussed adding fields to a data source and
other data sources within a data source. We also have the option within these data sources to add a range
which is created on a field or fields and specifies a searchable range or parameter for the query. And then we
also have the group by having an order by. For group by and order by, we can specify which field we want the
data to be ordered by in the query or which field we want the data to be grouped by in the query.

Lesson 8: Best Practices


In this lesson, we're going to look at some of the best practices to consider when creating tables, field groups,
and queries. Some best practices for tables include prefixing the name with the module name that the table
relates to. For example, cust vend or invent should be prefixed on the table name that relates to those
modules. Another example is to prefix it with a logical description of the table's contents. For example, cust
collection letter trends. For temporary tables, we prefix them with TMP. You can also post fix the table name
with the type of contents. For example, a table that contains transactions might end in the world trans or a
table that contains line level details might end in the word line, like sales line. The primary tables for the major
business areas are post fixed with the word table itself. For example, cust table is the master table for
customers. We also want to make sure we're setting the label property. This helps end users have a more
friendly name of what the table is and what it includes. For tables where the form ref property is set to display
menu item, the display menu item must exist. The title fields properties include title field one and title field
two. Title field one should be a key field for the records in the table. Use a descriptive title if the key field has
information for the user. Title field two should be a descriptive field for the records in the table. For example,
the table invent item group table, the title field one property is item group ID, and the title field two property is
set to name. If the value of title field one and title field two are the same, an error will occur. The table group
property is a mandatory property set to group for tables that contain grouping and categorization information.
Deleting records from a group table can sometimes result in an unstable situation. Enable confirm deletion for
this situation. Typical examples of group tables from the standard application are cust group and vend group.
The table type property is used to set which type of table it is, if it's a regular table or a temporary table. You
can use the set TMP table method to make a non-temporary table temporary rather than creating a copy of the
table and changing the property. This way, the two versions of the table do not become out of sync. There's
also the created and modified fields that can be added to the tables. Carefully consider if you need to track the
created by date and time along with the modified date and time. Only set these properties if you need this
information. Now let's look at some of the best practices for table fields. For table ID and rec IDs, we do not
want to directly use the system data types recID or table ID. Instead, we use the extended data types ref recID
for fields that refer to record IDs and ref table ID for fields that refer to table IDs. You should review the use of
memo and container fields in application tables. Memo and container fields have the following characteristics.
They add time to the application fetch and they add time to the database fetch. They also inhibit array fetching
and cannot be used in we're expressions. Consider using text fields with a specific number of characteristics
instead of memo fields. For example, use the addressing extended data type for the addressing fields. Or use
the item free text extended data type for the item description on order lines. We should also consider the
mandatory allow edit on create, allow edit and visible properties. Allow edit on create determines if you can
edit the field on a new record. You should use the allow edit property to indicate if you can edit the field on an
existing record. This is usually set to yes. When it's set to yes, the field will be editable when the record is
created. Set to no when the field would be set programmatically for new records. If the allow edit is set to no
and allow edit and create is set to yes, you can edit the field on a new record but not on saved records. The
visible property is usually set to yes but it can be set to no for system only information. That's information that
will not be shown in the user interface. Lastly, we always want to use extended data types or enums as fields
on the table. Fields that contain the same information should share the same extended data type or
enumeration. Let's look at some of the best practices for using field groups on tables and forms. You should
use field groups to organize related fields and related data. It's a best practice to use field groups when
designing forms as well, because when additional fields are added to the field group on a table, it will
dynamically update the form with the new field that was added to the field group. You should place at least
two fields in the auto report field group for each table except for parameter tables. The fields placed there
should be the ones that the user expects to print when they first click on print from the file menu to run the
auto report. The fields used for the title field one and title field two properties are often candidates for this
field group. If you do not put anything into the auto lookup field group, the auto lookup form will contain the
fields used in the title field one and title field two properties plus the field in the first unique index. Queries are
more flexible and allow the user to modify ranges and parameter criteria at runtime. They also allow for
sorting at runtime. Because of this, it's a best practice to use a query when the nature of data being selected is
not known at runtime. When possible, it's also a best practice to create queries by adding them to your
projects and editing them with the element designer instead of building them in code. Due to queries being
dynamic and flexible, it's a best practice to use them as the underlying data source for forms and reports.
Module Review
Thanks for joining me in the tables module. In this module, we looked at how to create new tables and the key
properties that should be considered for them. We also looked at how to add fields and data types to a table.
Additionally, we reviewed how to create and manage field groups and discuss the concept of table inheritance.
We then reviewed how temporary tables can be used and the various types of temporary tables that are
available. Finally, we took a look at the best practices for tables and fields, field groups, and queries.

MODULE 6 KEY TAKE AWAY


o Tables

 About tables

 Stores business transactions and metadata used in system

 Made up of records (rows)

 Table components

 Fields

 Make up data in the table

 Can be base enumerations or extended data types

 Field groups

 Logical groupings of physical database fields

 Used on forms and reports

 Indexes

 Speed up retrieval of data from tables

 Relations

 Define how table relates to records in other tables

 Delete Actions

 Not used

 Specified on properties of a table relation

 Methods
 Pieces of code added to a table executed when certain events occur

 State machine

 Enables workflow events to be bound to state transitions

 Mapping

 Associated map field with a field in one or more tables

 Adding Data Types

 Includes:

 Fields

 Base enums

 Extended data types

 About field groups

 Types of field groups

 Common uses for field groups

 Best practice checks for field groups

 Key Properties

 Table type

 Label

 PrimaryIndex

 ClusterIndex

 ConfigurationKey

 Support Inheritence

 Extends

 Table Inheritance

 Controlled by support inheritance and extends table properties


 Allows for sharing attributes or fields from a base table

 Temporary Tables

 Two main types

 TempDB

 InMemory

 Defined by the Table Type property value on the table properties

 Commonly used for reporting

 Queries

 May contain one or more tables as a data source

 Highly flexible

 Can specify details at the run time

 Reusable on forms and reports

 Best Practices

 Table

 Naming

 Labels

 Form reference

 Title fields

 Table group

 Table types

 Created and modified fields

 Table fields

 Table ID and Record IDs

 Memo and Container fields


 Consider mandatory, allow edit on create, allow edit and visible properties
carefully

 Always use EDT or enums

 Field groups

 Use field groups to organize related fields

 Use field groups to design forms

 Auto report should have at least two fields

 Auto lookup reverts to TitleField1 and 2

 Query

 Use queries instead of select statements when structure of “select” is unknown

 Create queries in the Application Explorer instead of X++ code when possible

 Always use queries as the data source for Forms and Reports

MODULE PRACTICE
Practice 6.1: Create Tables
Scenario

Two tables have been identified for the new fleet management module for Contoso including a table to store
basic vehicle information and a second table to store vehicle maintenance information.

The table for the vehicles will need to track the following information: fuel level, fuel type, gross vehicle weight,
inspection date, make, mileage, model, notes, number of doors, seating capacity, third row seating, a unique
vehicle ID, vehicle type, VIN and year.

The table for maintenance will need to track the following information: service type, engine description, service
start and end dates, and the vehicle ID.

For the Fleet Management Scenario Simon, the developer for Contoso, needs to create tables to store
information about the various types of vehicles in the fleet.

High Level Steps


1. Create Table
2. Add EDTs
3. Set Labels
4. Set Properties
5. Create Field groups
6. Repeat for remain table
7. Build
Detailed Steps
1. In the solution Explorer, right mouse click the DevelopmentBasicsFMS Project
2. Click Add > New Item
3. In the AX7 Artifacts, Choose Data Model
4. Click Table
5. Name: dbfmVehicleTable
6. Click Add
7. Drag and drop these fields over from Solution Explorer to the Fields node under
dbfmVehicleTable
a. dbfmInspectDate
b. dbfmMileage
c. dbfmFuelLevel
d. dbfmNote
e. dbfmServiceTypeCode
f. dbfmMake
g. dbfmModel
h. dbfmYear
i. dbfmNumberofDoors
j. dbfmSeatingCapacity
k. dbfmThirdRowCode
l. dbfmFuelTypeCode
m. dbfmVIN
n. dbfmVehicleID
o. dbfmGrossVehicleWeight
p. dbfmVehicleTypeCode
8. Right click dbfmVechicle Table in the middle pane and click properties.
9. Set Label to Vehicle Table
10. Set Title Field1: dbfmVehicleID
11. Set Title Field2: dbfmVIN
12. Right click on the Field Groups node in the middle pane.
13. Click New Group
14. Right Click FieldGroup1 and click rename. Change the name to Action and set Label
to Action.
15. Drag and drop the following fields from the Fields node to the Action node.
a. dbfmInspectDate
b. dbfmMileage
c. dbfmFuelLevel
d. dbfmNote
e. dbfmServiceTypeCode
16. Right click on the Field Groups node in the middle pane.
17. Click New Group
18. Right Click FieldGroup1 and click rename. Change the name to VehicleDescription
and set Label to Vehicle Description
19. Drag and drop the following fields from the Fields node to the VehicleDescription
node.
a. dbfmMake
b. dbfmModel
c. dbfmYear
d. dbfmNumberofDoors
e. dbfmSeatingCapacity
f. dbfmThirdRowCode
g. dbfmFuelTypeCode
20. Right click on the Field Groups node in the middle pane.
21. Click New Group
22. Right Click FieldGroup1 and click rename. Change the name to Identification and set
Label to Identification
23. Drag and drop the following fields from the Fields node to the Identification node.
a. dbfmVIN
b. dbfmVehicleID
c. dbfmGrossVehicleWeight
d. dbfmVehicleTypeCode
24. In the Solution Explorer, right click DevelopmentBasicsFMSProject.
25. Click Add > New Item
26. AX7 Artifacts > Data Model
27. Select Table
28. Name: dbfmVehicleMaintenance
29. Click Add.
30. Drag and drop these fields over from Solution Explorer to the Fields node under
dbfmVehicleMaintenance
a. dbfmServiceTypeCode
b. dbfmServiceStartDate
c. dbfmServiceEndDate
d. dbfmEngineDescription
e. dbfmVehicleID
f. dbfmNote
31. Right click dbfmVehicleMaintenace > Properties
32. Set the label to Vehicle Maintenance
33. Right click on the Field Groups node in the middle pane.
34. Click New Group
35. Right Click FieldGroup1 and click rename. Change the name to Maintenance and set
Label to Maintenance.
36. Drag and drop the following fields from the Fields node to the Maintenance node.
a. dbfmServiceTypeCode
b. dbfmServiceStartDate
c. dbfmServiceEndDate
d. dbfmEngineDescription
e. dbfmVehicleID
f. dbfmNote
37. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
38. Click Build (or use Ctrl+Shift+B)
39. Review the Output screen to review process. Should say “Dynamics AX7 build
completed”.

Practice 6.2: Create Queries


Scenario

In addition, each of the tables will need a query to return the data for forms and reports.

High Level Steps


1. Create a query
2. Set the title
3. Add the data source
4. Set the properties
5. Create any additional queries
6. Build
Detailed Steps
1. In the solution Explorer, right mouse click the DevelopmentBasicsFMS Project
2. Click Add > New Item
3. In the AX7 Artifacts, Choose Data Model
4. Click Query
5. Enter dbfmVehicleTable in the Name field.
6. Click Add
7. Enter Vehicle Table in the Title field.
8. Drag and drop dbfmVehicleTable under the Tables folder from Solution Explorer to the Data
Sources node.
9. Right click on the dbfmVehicleTable you just dragged over and select properties. Set the
following properties:
10. Dynamic Fields: Yes
11. Label: Vehicle Table
12. In the solution Explorer, right mouse click the DevelopmentBasicsFMS Project
13. Click Add > New Item
14. In the AX7 Artifacts, Choose Data Model
15. Click Query
16. Name: dbfmVehicleMaintenanceTable
17. Click Add
18. Enter Vehicle Maintenance Table as the Title
19. Drag and drop dbfmVehicleMaintentance under the Tables folder from Solution Explorer to
the Data Sources node.
20. Right click on the dbfmVehicleMaintentance you just dragged over and select properties. Set
the following properties:
21. Dynamic Fields: Yes
22. Label: Vehicle Maintenance Table
23. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
24. Click Build (or use Ctrl+Shift+B)
25. Review the Output screen to review the process. Should say “Dynamics AX7 build
completed”.
MODULE 6: YOUR NOTES
Module 7: Table Indexes
Welcome to the table index module. In this module, we'll define indexes and review the different types of
indexes in Dynamics AX. Let's begin by reviewing the objectives. The objectives for this module are to discuss
the main types of table indexes, to provide examples of each type, and then to demonstrate how to create a
new table index.

Lesson 1: Fleet Management Scenario


To continue to build upon our fleet management example, we will create indexes on our fleet management
tables for efficient data retrieval. Let's take a look at the scenario. The scenario is as follows. Simon, a systems
developer at Contoso, has evaluated the amount and type of data that will be stored in the vehicle tables. He
determines that an index should be added for the vehicle ID field will prevent duplicate entries in the table. In
addition, users will frequently search these tables by vehicle type and VIN number. So an additional index will
be created for each of these fields to help improve the data retrieval process.

Lesson 2: Index Types


In this lesson, we will review the main types of indexes used in AX along with examples of each type. The first
type of index that we're going to discuss is a primary index. A primary index provides a unique key to each
record in a table. This is the index that's used for record caching in Dynamics AX. In order to be a unique
index, the allowed duplicates property on the index must be set to no. This prevents the insertion of duplicate
key values in a table. The second type of index we're going to discuss is called a clustered index. A clustered
index organizes the data in the table in the order of the index. A clustered index can also be unique in the case
that the primary index and the clustered index are the same. A phonebook is a good example of a clustered
index. The data in a phonebook is first sorted by last name and then by first name. For each last name and
first name listed in the phonebook, there is a corresponding phone number and address. The data for a table
can only be organized one way; therefore, there can only be one clustered index. The third type of index we're
going to discuss is called a non-clustered index. A non-clustered index provides a way to quickly reference
data found in the clustered index using a specific set of columns. An example of a non-clustered index is the
index at the back of a textbook. You can look up the topic you want and the index provides you with a list of
page numbers that have information on that topic. For example, you could add a phone number index to a
phonebook so you could more quickly find an address by searching for a phone number. With this index, you
could look up a phone number then. This would provide a last name and first name, the key columns for the
clustered index. Next, you can use these to look up the address. This process involves a second lookup but is
much faster than looking at every phone number in the phonebook. The order of the columns in an index is
very important. For efficiency, an index should be organized from the most granular column, which means the
highest number of unique values, to the least granular column.

Lesson 3: Create an Index


We will begin by examining the process for creating an index on one of our fleet management tables. Indexes
are located within the element and type table in the development environment. They can be added by
opening a table in the element designer and navigating to the index's sub-node. An index is defined by one or
more fields on the table. It is used as a lookup criteria. When choosing which fields to use for a table index,
consider fields that are often searched by range or query or fields that are frequently used in joins. Indexes are
often used for performance reasons, to speed up data retrieval. An index can also be used to ensure the
existence of unique records and prevent duplicate entries into a table. Now let's create two indexes in our
dbVehicle table. Now, remember, this table stores all of the information about vehicles in our fleet. We added
a field called vehicle ID which is our internal unique identifier for our vehicles. So the first index we're going to
add is going to be a primary index on the vehicle ID field. To create the index, we go to the index's node in the
element designer for the dbVehicle table. And we can right click index and choose new index. I'm going to
press F2 to rename this and I'm going to call it vehicle ID, and then I'm going to suffix this with IDX which is a
naming convention for indexes. So once you have created this index, we have to specify which field in the
table we want to associate with it. So I'll right click the newly created index and choose new field. Now, we get
a blank field here initially. If we go over to the properties pane, there's a property called data field. And if we
click that, we'll get a drop down and it will populate a list with all of the fields in the current table. So I'll scroll
down and find my dbVehicleID field. OK. Now, if I go back to this index node, there's a property called allow
duplicates. It's currently set to no, and that's what I want for a primary index. We don't want to allow duplicate
entries on this field. This way, if someone tries to insert or create a new vehicle in my vehicle table that has the
same vehicle ID already in there, it will prevent that insertion of that record. So let's create a second index.
And this time, we'll create a clustered index. So I'll go back up to the indexes node and I'll right click and
choose new index. I'll rename this one description.IDX. And I'm going to add a couple fields. Actually, we'll
add three fields to this index. So right click and choose new. The first data field will be the DB make for the
make of the vehicle. I'm going to add another field. I'll go to my data field drop down and I'll choose DB
model. And I'll add a third field and we'll call this one the DB year. So now, this index has three fields for the
make, model, and year. And these fields are added to this index because they're commonly searched upon
fields. Now, remember, the order of these fields is also important in the index. We typically want to organize
them from the most granular to the least granular. So now that we've created these two indexes, a primary
index on vehicle ID and a clustered index and description, we want to set the properties in the table so that it
knows to use those indexes. So we'll go back up to the dbVehicle, the root node of my table, and in the
properties pane, we can go up to the behavior group and we can find the clustered index property and the
primary index property. So from the primary index, we'll choose the drop down and we'll see the two indexes I
have just created our available choices. The primary index was on vehicle ID so we'll select that. And the
clustered index which organizes -- which determines how the data is organized in my table was a description
index, and that included the make, model, and year. So I'll choose that one for my clustered index. And then
we'll save our table.

Lesson 4: Best Practices


There are many considerations to keep in mind when deciding if you should use an index. Let's review some of
the best practices. You should always maintain indexes in the development environment using the element
designer on a table. You should always specify a clustered index. This determines how the table should be
organized. You should also always specify a primary index to determine the unique key on the table. You
should only add an index if the speed improvements gained are greater than the cost to update the index.
Every time a table is updated with an index on it, the index must also be updated. And lastly, we should limit
the number of columns used in an index.

Module Review
Thanks for joining me in the table indexes module. In this module, we introduced the various types of indexes
that can be added to tables and the purpose for each type of index. Then we created new indexes and
reviewed the best practices for using indexes in AX.
MODULE 7 KEY TAKE AWAY
o Table Indexes

 Index Types

 Primary Index

 Provides unique key to each record in a table

 Used to record caching

 To be unique, Allow duplicates property must be set to No.

 Clustered Index

 Organizes the data for a table in the order of the index

 Non-Clustered Index

 Provides way to quickly reference data found in clustered index or heap using
specified set of columns

 Create an Index

 About indexes

 Indexes are associated with tables and make it easier to find specific data

 Defined by one or more fields on a table

 Improve performance of data retrieval

 Can ensure existence of unique records

 Best Practices

 Always maintain indexes in the development environment

 Always specify a clustered index

 Always specify a primary index

 Add an index if the speed gained by adding it is greater than the cost of updating
it
 Limit the number of columns in an index

MODULE PRACTICE
Practice 7: Create an Index
Scenario
For the fleet management scenario, we will need to add and index. For our example, we will have created the
table new. It is assumed that there is no data in the table before we begin. First we plan our index. Next we
add the required index to the table. Third we set the required parameters. Finally, we build our solution.

Simon, the Systems Developer at Contoso, has evaluated the amount and type of data that will be stored in the
vehicles tables and determined that an index should be added for vehicle ID for a more efficient link from
Vehicles to Vehicle Maintenance

High Level Steps


1. Create an Index
2. Build
Detailed Steps
1. Locate the table dbfmVehicleMaintenance in the Solution Explorer under
DevelopmentBasicsFMSProject, right-click it, and choose Open.
2. When the table designer opens, right-click the Index node and choose New Index.
3. Right click and choose properties. Enter “VehicleIDidx” as the index name.
4. Ensure that Allow Duplicates is set to Yes
5. Right Click VehicleIDidx index and choose New Field.
6. Right Click on the new field and select properties, set the Data Field value to
dbfmVehicleID.
7. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
8. Click Build (or use Ctrl+Shift+B)
9. Review the Output screen to review the process. Should say “Dynamics AX7 build
completed”.
MODULE 7: YOUR NOTES
Module 8: Table Relations
Welcome to the table relations module. In this module, we will introduce how relations function on a table and
discuss how and when you should create them. Let's begin by reviewing the objectives. The objectives for this
module are to define the different types of table relations, to define the on delete property on a relationship, to
create a new table relation, and finally, to review the best practices for table relations.

Lesson 1: Fleet Management Scenario


To build upon our fleet management example that we are developing for this course, we will create a relation
between two tables in our fleet management scenario. The scenario is as follows. Simon, the system's
developer at Contoso, has identified that the vehicle table and the vehicle maintenance table are related to
each other by the vehicle ID field. Each vehicle record in the vehicle table can be related to multiple
maintenance records in the vehicle maintenance table. It is important that you are not able to delete the
vehicle records if records already exist in the vehicle maintenance table.

Lesson 2: Relations
In this lesson, we will describe how relations function in tables as well as the different types of table relations
and their uses. A relationship is created between tables with related data. It defines how they're related and is
set on the relations node on a table element. When you create a relation on a table, you specify which field or
fields connect that table to another one. In the screen shot here, we have a relation. The name of it is EcoRes
product. And then the relationship itself is based on inventTable and the field called product within that table
and it relates to the EcoRes product table and the recID field within that table. Another example is that we can
have a customer table which has customer account number and general information about a customer such as
their name or location. Then we can have a customer group table which may have a list of customer account
numbers in one column and their corresponding groups in another. We can relate these tables on the
customer account number so that when we perform lookups in one table or another, we can find the related
records in each table. When creating forms, it's common to have related tables as underlying data sources.
These tables may be related in the query as well. We establish this relationship so that we can access
information in both tables by using a common field like account number or product. In addition to associating
rows in one table with another, relations can also be used to restrict the rows returned in a table and enforce
referential integrity. Let's take a look at some of the different relationship types and how they work in AX. The
first relationship type is called a normal relationship. A normal relation is used to specify a relation without any
conditions. In the field property, we select the field in the primary table that relates to a field in the present
table. In the related field property, we would then select a field in the related table. A field fixed relation is a
relation that's used to restrict records in the primary table. There's a field property which allows us to choose
which field in the primary table we want to use to restrict the records. There's also a value property where we
enter the value of a selected field to act as a filter. This relates only records in the primary table that match the
field value. Only numeric values can be entered in the value property. Field fixed relations can only be created
on numeric fields. Each of the related fields are ended in the table relation. They are combined. A related field
fixed relation is very similar to a field fixed relation except for it's used to specify the relation of the fields and
restrict records in a related table instead of the primary table. The same properties are used in set as in a field
fixed relation. We can only set a related field fixed relation on a numeric field as well. Another type of relation
is called a foreign key relation. This is used to specify a correspondence between a foreign key field in the
present table to the primary key field in another parent table. Foreign key relations are usually set on a child
table. We often refer to a child table as a table that has the foreign key. The on delete property value is
located within the relationship properties and it dictates what should happen when a deletion occurs. Since we
typically set the relation in the child table, the on delete property specifies what should occur when a related
record in a parent table is deleted. The purpose of this is to maintain database consistency when a record is
being deleted in a table that has related records in another separate table. There are four different properties
here that can be set on the on delete property. The first one is none. That means the row in this table is
deleted but nothing occurs to the tables that relate to this one. The second option is the cascade value for the
on delete property. And cascade means the row in this table will be deleted and all data in related tables will
also be deleted. The next value is called restricted. That means the row in this table will only be deleted if
there is nothing that relates to it in another table. This prevents deletion of a record that has related records
somewhere else in the system. The last option is called cascade restricted. The cascade restricted option
means to allow a cascade delete even though a record exists on related tables. This option causes a warning
box to appear to the user. If you click no, nothing will occur. If you click yes, then a cascade delete will run.

Lesson 3: Creating a Relation


Now let's take a look at the process for creating a relation between tables in Dynamics AX. So let's create a
relationship between our vehicle table and our vehicle maintenance table. We're going to create a foreign key
relationship on the dbMaintenance table. The maintenance table is known as the child table. And we always
set foreign key relationships on child tables. Now, the reason the maintenance table is a child table is because
it has -- multiple vehicle ID fields can exist within it. For example, in our main vehicle table, we have a vehicle
ID one which is a certain vehicle type. And then that particular vehicle can have many maintenance records in
the maintenance table. So for that reason, we call it a child table. To create a relationship, we go to the table
we want here in our designer and under the table node, we have an option for relations. We can right click this
and specify new and we can choose relation or foreign key relation. In this demonstration, we'll use a foreign
key relation. It creates the initial relation here and we can rename it by editing this name property or
highlighting it here and pressing F2. We will call this vehicle ID relation. Now, in the properties, the first thing
we need to do is specify the related table here. Now, the related table is going to be our vehicle table. You
can type it or use the drop down. I'll type it in there. And now we can right click this relation and choose new
and we have the option to choose a normal foreign key relation or a related fixed field foreign key relation.
We're going to choose a normal foreign key relation. It creates a new node here and a new properties pane
opens up. So the first thing we want to do is select which field here in this table in the maintenance table that
we want to include in the relationship. And that's going to be the dbVehicleID field. Then the related field, this
list is populated with fields based on the related table that we specified here. So when I go here and I click the
drop down, I will see fields from my vehicle table. And again, we want it to relate on vehicle ID. This field exists
in both places. OK. So once that's established, we can go ahead and make sure we save that relation. And if
we go back to the main vehicle ID relation node here, we can look at a few more properties if we're interested.
In particular, we discussed the on delete property currently set to none. We can set this to restricted. If we
want to prevent certain types of deletion. So this means if we go into the main vehicle table and try to delete a
vehicle, vehicle ID one, however, there's a maintenance record in the maintenance table for that vehicle, it will
not allow us to perform that deletion. So it's a way to kind of protect and ensure database consistency.

Lesson 4: Best Practices


There are many considerations to keep in mind when deciding to use relations between tables. Let's review
some of the important guidelines that should be followed when creating relations. When using table relations,
the name of the relation should contain the name of the table it relates to. This makes it easy to identify. A
relation should be defined in the table holding the foreign key. This is typically the child table. The validate
property on the relation must be set to yes, which is the default value for a foreign key relation. If you are
using a configuration key, the key that is specified for the field in a relation must be the same key or in the
same tree of keys as the one used in the related field. Navigational relationships do not enforce integrity
constraints but they're used for navigational purposes. For example, when a form is opened within another
form. The validate property on these should be set to no. Defining navigation relationships make the
application easier to navigate.

Module Review
In this module, we examined how relationships are used and the different types that exist in AX. We then
looked at some properties of relations and created a new relation for our vehicle maintenance and our vehicle
tables. Lastly, we reviewed some best practices to use when creating table relations.

MODULE 8 KEY TAKE AWAY


o Table Relations

 Relations

 About relations

 Defined between tables with related data

 Relations are set on relations node beneath a table element

 Useful for performing lookups for forms

 Enforce referential integrity

 Relation Types

 Normal

 Field fixed relation

 Related field fixed relation

 Foreign key relation

 On Delete Property

 Dictates what happens when deletion occurs

 Outcomes

o None

 Nothing occurs to related tables


o Cascade

 All data in related tables is deleted

o Restricted

 Row is only deleted if nothing relates to it

o Cascade + Restricted

 Delete even though recorxds exist on related tables

 Best Practices

 Name of relation should contain the name of the table it relates to

 Relation should be defined on the table holding the foreign key

 Configuration key specified for field in relation must be same key or in same tree of keys

 When using navigational relationships, validate property must be set to No

MODULE PRACTICE
Practice 8: Create a Table Relationship
Scenario
Simon, the Systems Developer at Contoso, has identified that the vehicle table and the vehicle maintenance
table are related to each other by the vehicle ID field in both tables.

Each vehicle record in the vehicle table can be related to multiple maintenance records in the vehicle
maintenance table.

High Level Steps


1. Create a Table Relationship
2. Set the properties
3. Build
Detailed Steps
1. Locate the table dbfmVehicleMaintenance in the Solution Explorer under
DevelopmentBasicsFMSProject, right-click it, and choose Open.
2. In the designer, right-click the Relations node, and then select New > Foreign Key
Relation.
3. Right click on the RelationForeignKey1 and select Properties Select the following
properties.
4. Cardinality – OneMore
5. EDTRelation – Yes
6. Name – VehicleForeignKey
7. Related Table – dbfmVehicleTable
8. Related Table Cardinaltiy – Exactly One
9. Relationship Type - Association
10. Right on the VehicleForeignKey and click New > Normal
11. Right click on the dbfmVehicleMaintenace. == dbfmVehicleTable. and select Properties
Select the following properties.
12. Field - dbfmVehicleID
13. Name – dbfmVehicleID
14. Related Field - dbfmVehicleID
15. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
16. Click Build (or use Ctrl+Shift+B)
17. Review the Output screen to review process. Should say “Dynamics AX7 build completed”.
MODULE 8: YOUR NOTES
Module 9: Form Patterns
Hi. Welcome to the module on form patterns. In this module, we will explore different examples of form
patterns as well as sub-patterns and their application within AX. The objectives for this module are to illustrate
form pattern examples. We will then run the form patterns report and understand the data within it. Then we
will apply patterns to forms. We will apply sub-patterns to form controls, and we will define important
properties.

Lesson 1: Form Patterns and Sub-patterns - Part 1


During this lesson, we will discuss form patterns and sub-patterns. Form patterns are applied to forms and
determine the specific layout as well as the controls and containers that are required for that particular pattern.
Sub-patterns are applied to certain controls or tabs on the form. Let's review the steps involved when deciding
which form pattern to apply. AX makes development easier by providing a guided experience for applying
form patterns to ensure they are correct and consistent. They help validate form and control structures and the
use of controls in certain places. Using patterns also ensures that each new form encountered by a user is
immediately recognizable in appearance and function. Form patterns can provide many default control
properties which leads to a more guided development experience. The use of form patterns also ensures
better compatibility with upgrades. In Dynamics AX, many of the existing form styles and patterns from
previous versions continue to be supported and those that are not supported have a migration path. The
foundational elements of Dynamics AX are being built with those legacy form styles and patterns in mind so
that the transition is as easy as possible. Applying a pattern is a straightforward process that can modify
properties on multiple containers and controls on a form. The standard flow for applying a pattern is to first
acquire the target. In other words, to decide which form you want to apply the pattern to. Next, is to
determine the pattern, to decide which pattern best suits your scenario to display the information you need to
your end users. Next is to apply that pattern. Applying a pattern is as simple as right clicking the form design
and choosing the pattern you want. Lastly is to deal with errors. After the pattern is applied, you can use the
pattern tab in the pattern information panel to make sure you add the correct controls in the correct order to
support that form pattern. We will look at an example of this in the next module when we create a form. After
you apply a pattern to a form, you can also apply sub-patterns to its controls. The process is similar to
applying a pattern to a form. You simply acquire the target, determine the sub-pattern, apply the sub-pattern,
and then deal with the errors. This time, the target should be a container control on a form, somewhere under
the form design. The control should have a pattern unspecified in its name. You right click the control in
question and you can select apply pattern and then choose from a list of sub-patterns that you wish to apply.
Dynamics AX has nearly 40 form patterns that you can apply to your custom forms. We will demonstrate
examples of about five different form patterns. The first one is the details master form pattern. This is a
primary method for entering data into Dynamics AX. These form patterns allow the user to view, edit, and act
upon data. All content in these form types is structured into FastTabs which can then be expanded or
collapsed, allowing for multiple FastTabs to be open at the same time. Form part FactBoxes are another form
pattern we will look at. In general, these are used to provide related information for a record. They make sure
the user does not have to open additional forms to get important information that they need such as totals,
balances, or overdue orders. The FactBox grid pattern is used when there is a child collection or potential for
multiple rows of related information. A FactBox is created as a separate form with the FactBox pattern applied
and then added as a part on another form. The simple list pattern displays details for a simple entity as a grid.
This typically will have six fields or less per record with no child parent relationship. However, there can be
exceptions where a simple entity may contain up to 15 fields. A list page is another type of form pattern which
still displays data in a grid format. However, it may be data relating to a more complex entity. The fourth type
of form pattern we're going to demonstrate is called a table of contents or setup page. This type of pattern is
used on a form to display setup information. It's commonly used as a setup or parameter page that are
frequently accessed through the navigation menu as well as through workspaces. This pattern should be used
when two or more logically related forms are needed for configuring setup. There's a vertical arrangement of
tabs on the left which implies the order of completion. And finally, the last type of form pattern we're going to
discuss is called the operational workspaces pattern. Workspaces are a new concept that takes over as a
primary way to navigate to tasks and specific pages. A workspace must be created for every significant activity
supported in the product. Such an activity is less granular than a task but more granular than a legacy area
page. The workspace must provide a one-page overview of an activity to help users understand the current
status, the workload ahead, and the performance or of the process for the user. There are two types of
workspace form patterns: the traditional workspace and the operational workspace. It's always encouraged to
use the operational workspace as it has superior performance characteristics due to the set of components it
contains.

Lesson 2: Form Patterns and Sub-patterns - Part 2


In this demonstration, we're going to look at how to run the form patterns report. This report is generated
through Visual Studio and gives us information about all of the forms in the system with the corresponding
form patterns. To run this report, we go to the Dynamics AX menu, and from the add-ins menu, we choose run
form patterns report. This will generate a CSV file that we can open in Excel. When the report is finished
generating, you'll be notified with a dialog box. It gives you the path and the name of the report. So we'll
navigate to this path to open the CSV file. I'll go to my documents and I can open my PatternsReport.CSV file.
So we'll notice in Excel, we have columns that tell us which model the form is in, the system name for the form,
as well as the form style and the form pattern. In addition, it gives us information about the controls and the
percent of coverage. So we're free to now sort and filter and organize this list so we can determine which
system form has which pattern applied, and also which forms do not have any pattern applied. So if I want to
sort on this particular pattern column, we can go ahead and apply sort. And we can put it in alphabetical order.
In addition, we can go ahead and filter on this column and we can look at all the different pattern types. So if
we want to see, you know, which forms use a specific pattern, we can just choose one pattern and see those
forms. We can also choose which forms do not have a pattern. So we can unselect all, and we'll navigate down
and see where the blanks are at. So we can see these blank values for the pattern indicate that this particular
form does not have a pattern applied. This can give us some guidance when developing to make sure that all
the forms we have in our system have an appropriate pattern. This will help provide consistency in the UI and a
better end user experience. So let's take a look at how a details master form pattern looks like in a UI. We are
currently looking at a list of all customers. The system name for this form is cust table. By default, this opens in
a grid view so we have a list of all of our customers along with their account number, customer group,
currency, and telephone number. We have a control here called a quick filter that allows us to filter the data in
this grid. We can also switch from grid view to details view for a particular customer by doing one of two
things. We have the option to simply click the account number here for a particular customer and it will launch
the details view of this details master form. And the details view contains a lot more information about our
customer entity. We have FastTabs that organize related information about this customer, such as addresses,
contact information, and payment defaults, et cetera. We also have our summary fields here which give us
some quick insights into what is within this particular FastTab without opening it. At any time we can switch
back to our grid view by using the back button in our browser. We can also use this options button up top and
go to change view to switch between grid and details view at any time. From our page options, we also have
the ability to perform advanced filtering and sorting as well as retrieving some more record information. So
let's take a look at how this form looks in the development environment in Visual Studio. So I've opened the
cust table form from the Application Explorer. I used the search feature to filter my results. And I have opened
it in the element designer. When you open a form, you will have two panes. On the left, we have some general
information about this form such as methods and events as well as data sources and form parts. In the right
pane, we have our area where we design the form. We apply our form patterns and then we add the
appropriate controls here that will satisfy the requirements of the pattern. So now let's take a look at the two
different types of FactBox patterns. There's the FactBox grid which is used when there's a child collection with
the potential for multiple rows of related information. There's also the FactBox card which is used when there's
simply a set of related fields. So I'm here again in the UI on my all customers cust table form. Now, I have a
particular record selected in my grid view here. And to open the FactBoxes, I click this little blue arrow off to
the right that's pointing onto the screen. It will open a fly-out menu with these different tabs. The first one
here is statistics that I have opened is a FactBox card, is displaying just a few sets of related fields that relate to
the selected record. If I expand the contacts tab, this opens a FactBox grid. We can see it's a little mini grid
with just two columns that are displaying some contact information for my selected customer. And we can
hide the FactBoxes by simply pressing this arrow. And now we can go check out how they are set up and what
they look like in the development environment. So in my form design here, I have my cust table form open
again, since this is the form we were just looking at that had those FactBoxes. If I expand the parts, we can see
that cust statistics, statistics, and the ContactsInfoPart. These were the examples of the FactBox grid and
FactBox card. Now, if I search for these parts in the Application Explorer, for example, I will type in
ContactsInfoPart. I'll be returned with a form and it's called contact info part. Now, if I right click this one and
choose open in designer, we can see that this ContactsInfoPart form has the pattern, form pattern FactBox grid
applied. Likewise, if I were to search for the customer statistics statistics form part, it would open up a form
that has the design pattern applied for the form part FactBox card. So these FactBoxes are created as a
separate kind of form and they have a pattern applied, and then they are added onto the form as a part that
you want to display them on. The third type of form pattern we're going to demonstrate is a simple list
pattern. So I'm here at the main page of a dashboard in my Dynamics AX UI. And I'll click up here on the
navigation menu. And I'm going to navigate to accounts receivable. And I'll go the setup page. And I'll go to
customer groups. This form demonstrates the simple list pattern type. We can see there's only five different
columns here, five different fields, and a small list of different customer groups. So this is really the epitome of
what a simple list type pattern would look like. Again, this form pattern does support the quick filtering, even
though we only have a handful of records here. You could potentially have more and then go ahead and filter
your simple list using the quick filters control. In this demonstration, we're going to look at the table of
contents form pattern. This is also known as a setup page. A good example of this is the accounts receivable
parameters. So we'll navigate to our navigation menu and choose accounts receivable, setup, and then
accounts receivable parameters. So here we have our table of contents form pattern. Now, we can see along
the left here, this is called the vertical tab style. They are arranged in a sequential order of these parameters
that need to be set up. So each option here at the left is a tab choice and has a different page that relates to
some type of setup information. This pattern should be used when two or more logically related forms are
needed for configuring setup. This form pattern contains a collection of smaller content regions that each
follow a container pattern similar to a simple list. In this demonstration, we're going to look at an example of
the operational workspace form pattern. A good example is located in the product information management
area. So we'll go to our navigation menu. I'll go to product information management and then we have this
next area called workspaces. And then I'll choose released product maintenance. So this is the layout of an
operational workspace. It's intended to provide an overview of a specific activity, including the current status
and summary of particular items as well as the workload ahead. So we notice these objects over here are
clickable and they're called tiles. Windows 8 introduced the concept of tiles, and you'll see them used in
Dynamics AX, especially on operational workspace form patterns. It's essentially a rectangular button that
behaves just like a menu item. You can click it and navigate to different pages. You can navigate to reports as
well as outside URLs. In addition, tiles can display relevant data such as a KPI, a key performance indicator,
which displays information such as total revenue. Tiles can also include images that provide the user with
some type of visual context. You'll notice we have these three kind of panes here on the left, the summary
pane with the tiles. In the center we have more information about specific released products, and then a third
pane over here is a stopped released products. And then finally, we have a section with different links that we
can quickly get to related pages.

Lesson 3: Form Patterns and Sub-patterns - Part 3


After you apply a pattern to a form, you can apply sub-patterns to a form's controls, like a tab page, for
example. You may notice a control that says pattern unspecified after the name. This means there is no sub-
pattern applied to that control. However, one may be added. The process for applying sub-patterns is similar
to applying a pattern to a form. We acquire the target control. We determine which sub-pattern we want to
apply. Then we apply the sub-pattern. And finally, we handle the errors. This time, the target should be a
container control on a form somewhere under the form design and the control should have this pattern
unspecified designation after the name. We can then right click that control and choose apply pattern and
click the sub-pattern we want to apply. The available sub-patterns include sub-patterns that can be used to
migrate controls from previous versions of AX. There are many available sub-patterns in AX so let's look at
some examples. Some common sub-patterns that may be applied to a form's controls include custom filters
and custom quick filters. These are used where filters are modeled on the form. Custom quick filters is very
similar to a custom filter. The only difference is that the form pattern requires the quick filter sub-control.
Image preview can be used for most images within a form container, especially within a FastTab or group. This
could be used in conjunction with the fields and field group sub-pattern for combining images and any
associated fields. It is not used for tiles or buttons or the field status images. The fields and fields groups sub-
pattern provides a responsive layout for containers that contain only fields. For example, a tab page containing
a FastTab. Selection tiles show a set of tiles or charts in a workspace section. This should be modeled on a tab
page in a workspace form. In this demonstration, we're going to look at the sub-pattern of custom filters. And
here we're looking at our general journals form. If we right click the form, we can find out form information
and it tells us the system name of the form which is ledger journal table. So our custom filter sub-pattern is
being applied right here. It's allowing us to choose this combo box to show all general journals posted or not
posted. We also have an additional filter which is a checkbox where we can show user created only journals. If
we go to the all customers form, we can also see an example of the sub-pattern custom quick filters here. This
one, however, is not configured as a combo box but simply we can type in any values we want and filter a list
of customers. OK. So let's go into the development environment and take a look at how this custom filter sub-
pattern is applied on the ledger journal table form. So I'll click back into Visual Studio and I've opened the
ledger journal table in my form designer. Now, if I go over here to the right, I can see we have this group
called top fields and the sub-pattern applied is called custom filters. So again, the main pattern of the form is
applied up here on the design node and this form pattern is called task single. Then, within our groups and
our tabs and controls, we have sub-patterns we can apply to some of those. And you can see if we expand this
group, we have our two different filters, the open posted field combo box and then the show user created only
checkbox. And you'll notice once I click this group here, a blue rectangle outlines the portion of the form here
in my preview pane of where those are located. And if I select this combo box, again, it references that specific
filter right here. So now let's take a look at the image preview sub-pattern type and the fields and fields group
sub-pattern. And both of those can be illustrated on this form here. It's the POS visual profiles form. Now,
again, I can right click into any of those controls here and click form information and I can find the form name
which is the name of it in the system and the development environment and that is retail visual profile, and
then the control name which is screen. Now, if I expand this log-in background FastTab, this illustrates the
image preview sub-pattern type. Again, if I right click, we can see this control name is called log-in and this
one here is called general. So let's go take a look at how these are set up in a development environment. So
I'm going to go back to Visual Studio and I've specified this search query here in the Application Explorer to
return me that retail visual profile form by using the type followed by a colon and the word form which
specifies which type of element I'm liking for, and then followed by space and the actual name of the form.
That returns me with this element here, so I have right clicked and opened that in my designer. Now, again, we
can see on the design node the form pattern for this entire form is the simple list and details list grid form
pattern. Now, if I click into these different tab page controls and I can begin looking at my sub-patterns. So I'll
expand this details tab. We can see the general control and the log-in control. The log-in control uses the
sub-pattern of image preview. The general tab page control uses the pattern of fields and fields groups. Now,
again, the fields and fields groups sub-pattern provide a responsive layout for containers that contain only
fields. It's a good example to use on a tab page that has a FastTab just like we have here. We have these
different fields and field groups, so then we're using our field and field group sub-pattern. Now I want to
demonstrate an example of a selection tiles sub-pattern type. To do that, we'll go a workspace form where we
can commonly find these selection tiles sub-patterns. So from the navigation menu, we'll notice this option
here, all workspaces. If I choose that, these are all these different out-of-the-box system workspaces. I'm
going to go down here and choose sales order processing and inquiry. It will open up my workspace. Again,
we have these three kind of columns here that we can use in our workspace form pattern. So the one we want
to focus on here is this left area where we have our selection tiles sub-pattern. And again, these tiles are
clickable objects. I can click this one here and it will open up the all sales orders details. I can also click here to
access all customers, and then we have these different KPIs that are showing the amount of confirmed sales
orders and orders on hold. Now, let's take a quick look at how this looks in a development environment. So
I'm going to go back to Visual Studio and again, I've created a query to find this form in the system. I have
opened it up here in my element designer, and I can see that the form pattern for this entire form is the
workspace operational form pattern. And then if I expand this panorama body tab, we can see that the
pending orders tab page is configured with the sub-pattern of selection tiles. And that's what we see over here
in the left pane. You'll notice when we click that, the blue rectangle is highlighted on that area of the form. I'll
also point out that this panorama body tab is a tab style called panorama. And that's often used on
operational workspace form patterns as well. It kind of signifies this entire horizontal layout, that kind of three-
pane setup that we see in the UI. Now, we mentioned that applying sub-patterns is very similar to applying a
normal form pattern. And to illustrate that, I'm going to show you here on the sales order processing
workspace form that we've already opened, and we can simply right click one of these tab page controls. And
for the sake of example, I will remove the pattern since there is one already applied, and we can see now we
have this pattern and then select next to it which indicates that there is no pattern, sub-pattern applied to this
control. So to add one, we can simply right click our tab page control and we'll go to apply pattern and we can
see the only option for this one is selection tiles. And we can go ahead and apply it. Depending on which type
of control you have and which type of main form pattern is applied, that will dictate which options you see
when you go to apply a sub-pattern.

Lesson 4: Layout Properties


In this lesson, we'll look at some of the commonly used properties to determine a form's layout. One form
property we want to discuss is the view edit mode property. And this is set on the design node of a form.
There's the auto value which opens the page in view mode by default. And that mode has an edit button
which toggles the done, save, and restore buttons. It's important to note that some page styles do ignore the
view edit mode property, and an example of that is a dialog box. So setting the view edit mode property to
view means the page opens in view mode as well and it has no buttons that are related to editing the page.
It's always view only. If we set the view edit mode to edit, the page opens in edit mode which means it has the
save and restore buttons and the page is always editable. So then we can add an edit records to our form.
There's also an allow create and an allow delete property which is located on the root data source of the form.
Setting the allow create property to no means the page is read only. It has no new or delete buttons on that
form to allow any insertion or deletion into the underlying data source. If we set allow create to yes, this
indicates that the page allows creation of records and it has a new button. Setting the allow delete to no
means the page does not allow deletes. You cannot delete data from the underlying data source. If we have
the allow delete property to yes, that means the page does allow deletes and you will see a delete button on
that form. It's important to note there's also a show/hide property on the form design node that allows the
developer to choose whether or not they want to show and hide the new and delete buttons. We're now
looking back at the cust table form to demonstrate some of the different types of form properties. On this root
form node, we have a data sources node. And if we expand that and select one of the data sources such as
cust table, we can then explore some of the properties on this data source. So we can see that we've discussed
the allow create and allow delete properties and it's set to yes for this data source. These can be defined on
the individual data sources that live within the form. If we go over to the design node, we'll notice some other
properties. The caption property specifies which text we're going to display at the top of the form which is
right here. This is a system label that refers to the text customers. So if we were to go to the Dynamics AX
menu and go to find labels and I type this label in, you'll see it returns a result with this label ID that
corresponds to the value of customers. We also have the options for showing the delete and showing the new
button in our view edit mode that we discussed, which is set to auto for this form. If we go with an individual
tab or control here, we can see additional properties. These controls have properties such as the arrangement
method of the controls and fields here. We can also expand if we go to our tab page grid which shows the
grid of data, and we go to our actual grid control, we can see there's a data source property on the grid control
as well that specifies which data source on this form node is being used on this grid. And that uses the cust
table since that's where most of the customer information is stored.

Lesson 5: Check Form Pattern


In this lesson, we will cover the form pattern tab which is located in the pattern information panel. This is a tab
in Visual Studio that allows the developer to monitor the form development process and to make adjustments
where needed. It displays which controls are required and where they are needed to satisfy the requirements
of the chosen form pattern. The form pattern tab shows a visual representation of how the form should be laid
out. This allows for guided development. If a different sub-control is clicked like a tab page, the pattern tab
will then update its visual with the needed components that fall beneath that particular control. This allows the
developer to ensure that every control has the pieces needed to maintain the pattern consistency. It also
notifies the developer of any errors that are in need of correction, and then it will indicate missing controls with
a red rectangular box. The form statics dialog can be opened by right clicking the root form node and
choosing add-in, then form statistics. A well-designed form will show a statistic of a hundred percent pattern
coverage. This gives you guidance in terms of making modifications to a form. This dialog also shows a
summary of different form statistics such as the control count, the data sources count, and the method
override count. It gives you the form pattern name as well as the percentage of controls that are covered by
the pattern. When you apply a form pattern like the details master in this example, the pattern tab will show
you the additional controls needed to adhere to that form pattern. We can see we have the application bar,
the navigation list, and the panel tab. These are the three subcomponents that need to be added to satisfy the
requirements of this form pattern. In parentheses, we have the system type of sub-control to add, so this is the
group type, this is the action pane, and this is a tab control. We also notice these checkmarks next to each
name. These checkmarks indicate that each of these controls and their sub-controls within them have been
properly added in the correct order. If you happen to see a red rectangular box around any of these controls,
that indicates that there's an issue with this control or some of the controls within it. The main issues can be
that the control's missing or that it's not in the correct order to satisfy the pattern. We will look at a
demonstration of this functionality step by step when we create a form in the next module.

Module Review
Thank you for joining me in the module on form patterns. In this module, we looked at several examples of
different form patterns and sub-patterns as well as their applications in the form designer. We discussed the
important properties for form layouts and then we reviewed how to monitor the progress of a forms
development using the form statistics add-in and the form pattern tab.

MODULE 9 KEY TAKE AWAY


o Form Patterns

 Form Patterns and Sub-Patterns

 About Form Patterns

 Provide many default control properties

 Allow for guided development

 Create consistency and ensure better compatibility with upgrades

 Steps for Applying Patterns

 Acquire target

 Determine pattern

 Apply pattern

 Deal with errors

 Form Pattern Types

 Details master

 Form Part Fact Boxes

 Simple List

 Table of Contents
 Operational Workspaces

 Sub-Patterns

 Can be added to various form controls

 Can be prefixed with Pattern:<unspecified> after the name

 Applied in similar manner as form patterns

 Sub-Pattern Types

 Custom (Quick) Filters

 Image Preview

 Fields and Field Groups

 Selection Tiles

 Layout Properties

 Value: Auto

 Opens page in view mode

 Has an edit button

 Value: View

 Opens view mode

 Value: Edit

 Opens in edit mode

 Form.RootDatasource.AllowCreate

 Value

o No

 Read only page

o Yes

 Allows creation
 Form.RootDatasource.AllowDelete

 Value

o No

 Can’t delete

o Yes

 Can delete

 Check Form Patterns

 About Form Pattern Tab

 Allows for guided development

 Ensures consistency

 Notifies user of errors and areas in need of correction

 Form Statistics

 Dialog shows

o Summary of form stats

o Form pattern name

o Percentage of controls that are covered by the pattern


MODULE 9: YOUR NOTES
Module 10: Form Creation
Welcome to the form creation module. In this module, we will look at the form creation process and review
some of the different types of form controls. The objectives for this module are to create a form, to add data
sources to a form, to define the important types of form controls, to add controls and data types to a form, and
to apply patterns and sub-patterns to forms and form controls.

Lesson 1: Fleet Management Scenario


In the last module, we reviewed some of the different form patterns. Now let's begin creating forms to use
with our fleet management scenario. We'll create two different forms to help us effectively display data to our
users. The scenario is as follows. Simon, the developer for Contoso, needs to create a list page form and a
details form to properly display information for the fleet management system.

Lesson 2: Create a Form


In the first lesson, we will create a form to display information to the end users. The physical presentation of
forms and controls is now HTML, JavaScript, and CSS within the browser. In this demo, we're going to create
two forms to add to our project. And to do this again, we repeat the steps for adding elements by right
clicking our project, choosing add, and choosing new item. The forms live here in the user interface group. So
we'll select this group and we'll choose form as our element type. And for the first form, we'll call this
DBVehicleListPage. Because we're going to end up applying a list page form pattern to this form. OK. So we
have our new folder for forms and our very first form. So I'll go ahead and do this process again for our
second form. And we'll call this one dbVehicleMaintenance. OK. So we have our two forms opened here in
the element designer. So first let's set the caption property for this form. So my dbVehicleMaintenance form,
if I go here to my properties pane, we'll see a property called caption. And this is essentially the heading, what
we'll see here on the form. So we want to make this a user friendly, a descriptive phrase. We'll just call this
vehicle maintenance. And we'll notice it appears here in my preview pane. OK. So I'll click the tab for the
VehicleListPage form. And for the caption property, we'll just call this all vehicles as this will be a list of all the
vehicles in our fleet management system. And again, we see the heading appear. So we'll go ahead and
choose save to save both of our forms. And we can see now we have these two panes in our form element
designer. On the left, we have our root form node, the dbVehicleMaintenance form. And within that, we have
methods and events for adding code. We also have our data sources and our form parts where we can add
things like FactBoxes. And the right pane is where all the design will occur. We can see right now we have this
pattern unspecified. We have this new form, it's a blank canvass, and we can right click and apply patterns to
this form which would then begin the process of actually designing and adding controls. And as we continue
to add our controls, we can see them appear here in our preview pane. In our pattern pane, we will see the
different controls that are required for the pattern and the order they are required in. So we'll take a look at
adding data sources and elements and designing the form in our next demonstrations.

Lesson 3: Form Controls


Now that we've created a form, we need to add a data source and form controls so that we can define the
layout and display information. Let's begin by reviewing some of the types of form controls. First, let's review
some of the various controls that you can add to forms. Certain form patterns require certain controls to be
added in a particular order. This ensures consistency in design. Some controls are nested inside of other
controls. For example, a tab page can have more tab pages in groups beneath it. There are two panes in a
form element designer. The right pane is where you will find the root form.design node. And from there, we
can begin applying patterns and adding controls. You're also able to add group containers. These help
organize how the form will store information. A tab control can be used to create FastTabs, vertical tabs, drop
list tabs, and panorama tabs. These are all configured using the tab style property. And we'll demonstrate
examples of each of these. There's also another control called a grid. This is a special type of control that has
some container behaviors such as flexible sizing. Grids display data in a table-like format. So now, let's take a
quick look at the different types of tab styles. Now, these are set using the style property on a tab control
within a form. The first one we're going to discuss is the tab style called tabs. Now, this is your standard tab
page where we're clicking the tab from up here. So here's an example. Tab page 1, tab page 2, with each tab
containing different information. Obviously we can add some more tab pages to continue building these out
to the right. It's up to you. However many you want to have. The tab style of vertical tabs is actually what this
form uses here because we're clicking through these vertical tabs here on the left. And that's kind of just re-
represented here in example where we have tab page 1, and we have some information, some fields, tab page
2, some more information and fields, and we can continue adding these just like we have here to the left. Now,
the tab page vertical tabs is very commonly used with the table of contents form pattern which is used on
setup pages. For example, when we're setting accounts receivable parameters, we would have a tab page that
relates to some type of information. The next tab page where we can set some other information. So that's
the concept of the vertical tabs. It's a vertical list and we click them and we have different information within
each one. The tab style of FastTabs, this is commonly seen on details masters forms where we're looking at the
details of some entity, for example a customer. We have this ability to kind of expand and collapse these
FastTabs by using this arrow and when we expand them, we see information, some fields related to a particular
kind of group. For example, we could have addresses be the name of this FastTab. And then within it, we have
things like address line one, address line two, zip code, et cetera. Now, the tab style for panorama, you actually
don't have to click to get to the other tab pages like we saw in the previous examples. It's kind of a horizontal
layout within the same page. So for example, this kind of column here is the tab page one. And we scoot over
and we have our tab page two column and we can continue adding more columns that kind of represent a tab
page within the same view. And the panorama style is very commonly used on the workspace form patterns
and the operational workspace form patterns. It kind of creates this panorama of different activities within
these certain kind of panes or columns within the page. The last tab style is called a drop list. And this is
represented by a little drop down arrow and we can choose from a list of tab pages within that drop down.
And again, each tab page has its own kind of set of information within it. The action pane or application tab
runs across the top of a form and contains buttons and tabs to perform certain actions within that form. In the
screen shot, the action pane is the gray strip of buttons. By default, certain form types will already contain the
edit, new, delete, and modify buttons. These help change records within a certain form. It also currently
consists of system-defined actions. These are actions that aren't explicitly modeled. It also contains developer-
defined actions. These are actions that are modeled in button groups and placed directly under the action
pane on a forms design node. When an action pane tab is clicked, a file menu opens, which contains various
button groups and links to perform certain actions. We can see that this purchase order action tab opens up a
fly-out menu here with several different button groups. For example, the maintain button group which
contains two buttons. Request change and cancel. Action panes are modeled by using the following basic
structure. Note that in Dynamics AX, button groups can also be placed directly under the action pane which is
the case in the screen shot. Our action pane resides here and we have a button group directly under the action
pane. Within the action pane form control, you can set up button groups and buttons to perform certain
actions. Some of the different types of buttons in AX include the standard button for which the entire
functionality must be implemented in code. Then there's the command button which specifies a command or
a specific task to run. We then have the menu item button which specifies a menu item to navigate to or to
run. Next there's the drop dialog button which opens a fly-out dialog box, the contents of which are retrieved
via a menu item. And lastly, we have a menu button. This button container opens a fly-out which contains a
list of other buttons. Tool bars are action panes for which the style property is set to strip. They are used for
actions that have a specific context or aren't page level actions and also, primarily for actions that are specific
to a FastTab, tab, or grid. In this example, we're looking at the addresses FastTab on the customer details form.
In the screen shot, the tool bar is represented by the add, edit, and map buttons right here. Tool bars were
previously known as action pane strips in previous versions of AX. A grid control in AX is the primary tool for
presenting data and letting users interact with it. There are currently three different grid styles that are
implemented and supported, and those are tabular, list, and simple read only. These are set using the grid
style property. The tabular style grid is the traditional multicolumn grid. To present data in a tabular grid, we
set the style property to either auto or tabular. A list style grid is a single column stacked format. To present
data in a list grid, we set the style property to list. In a simple list grid, when the width mode is set to auto, the
width of the grid is determined by the widest field. Other fields are arranged in a left-to-right stacked manner.
The simple read-only grid style displays read-only data in a grid format. It is often used on form parts such as
FactBoxes or info parts and displays a small bit of read-only information. Let's take a look at some visual
examples of the different grid styles that we've just discussed. The first one is the list style grid. And this is
represented here in this left pane. If we click this blue grid-like icon on a form, it will pop out a list style grid
like this. We have this grid configured to show a customer's name and phone number. This is a scrollable
pane here on the left-hand side of our form. It also contains a filter so we can filter this list. Next, we have our
tabular style grid. And again, this is a traditional table style grid. It contains many rows and many columns. It
also has the ability to be filtered and edited as well. And finally, the simple read only style grid has a start date
and end date for a particular employee. And this is read only data. This is represented here in a FactBox that
would live on some other form.

Lesson 4: Adding Elements


In this lesson, we will add elements to a form. The first item we need to add is a data source. We will specify
which table or query we want to add to feed data into the form. Now that we have our two forms created and
we've set up our captions, let's go ahead and add data sources to each form and apply our form patterns to
each form. So I'll start here with my dbVehicleMaintenance form. And I will add a data source from my project.
And what I'm going to do is expand my simple queries folder and I'm going to use my dbVehicleMaintenance
query as the data source for this form. And I can simply click it and drag it out here to the data sources node
on my form. And remember, when we created this dbVehicleMaintenance query, we added two tables. The
dbVehicle table and the dbMaintenance table. In the query, we nested them and related them. However, here,
on the form, they just show up in a kind of list format, just to specify which tables are actually included in this
data source. So that's a quick way to add a data source to a form. And to apply our pattern, we'll go over here
in the right pane to our design node. We can right click. And we'll choose apply pattern. And for this form,
we're going to use one called task single. And we'll notice here the pattern tab automatically populates with
these different controls that are required to create this form with the task single form pattern. And these are
the order that they're required in. So we'll take a look at building these out step by step in another
demonstration. For now, let's flip over to our DBVehicleListPage form and I'll click my tab here since it's already
opened. And again, I'm going to add a query as a data source for this form. I'll choose my dbVehicle query.
Drag it on to the data sources node. And we'll see this query only has the dbVehicle table so that's what we're
getting. And now, we'll go over to the design node. We'll right click and we'll choose apply pattern. And for
this form, we're going to use a list page pattern. So I'll choose that. Again, we see our controls that are
required for this pattern. They're currently all highlighted in red because they have not been added yet. It's an
indication that we need to add those to satisfy this form pattern. So for now, we'll go ahead and save all, just
save the changes that we've made to both forms. And then in the next demonstration, we'll go ahead and
begin adding these controls to build out the actual design for both of our forms. Now that we have our form
pattern, let's go ahead and start building the actual controls we need for this form. And in this demonstration,
we're going to build out our DBVehicleListPage form which uses the list page form pattern. To begin adding
controls, we simply right click on the design node and we'll choose new. And from here, we have all these
different types of controls that can be added to the form. However, we want to follow what's in this pattern
tab here. So it's showing us the first one we need is the application bar, and parentheses, it's called action
pane. This is typically the name that we'll see here in our form pattern list. So action pane is right here. I'll
choose it. And we can see once we choose this control, the form pattern automatically refreshes with the
requirements for this control. So if we go back up to our design node, we can go back and see which controls
are needed for the overall high level design. And as we start adding these, more controls will be required for
the sub-controls. So let's go ahead and continue building out our main design node here. So we've added our
action pane. Now we need to add a group control. So again, I'll right click. I'll choose new. And I'll go down
-- it's in alphabetical order -- to find the group. And I'll choose that. And we can see this particular control has
this pattern and then a select designation which means this one will allow to you add a sub-control to this
particular control, or a sub-pattern to this particular control. So go back up to my root design node again. You
can see that the application bar and custom filter group have been added. Now I need to add a grid. So right
click the design node. I'll choose new. And I'll go to grid. OK. So let me go back up to my design node and
we can see now there are checkboxes next to each type of control to indicate they've all been added and they
are in the correct order. Now, if I click my action pane control, there's no requirements here for this sub-
control. So that one is good to go. If I choose my form control group one, again, this one doesn't have any
specific requirements. And the grid control does not have any specific design requirements. However, we can
definitely set some properties on these so a good idea would be to set the caption and the name if you wanted
to rename this particular action pane. We can also do that for each control so the group, if this was
representing a specific group, so maybe this is going to be now vehicles. OK. Now, for our grid, this is where
we are actually going to display data on the form. So what we need to do in the properties for the grid is go to
this data source property which is within the data group, if you have your properties pane organized by
category, and we can choose the drop down next to data source and we'll choose dbVehicle. This is our main
table that's going to be the data source for this form. And we're also going to use this as a data source in our
grid which is ultimately going to display data to the end user. OK. So now that we have our grid, we can begin
adding different fields to this grid. So for example, if I expand my data sources in the left pane, and I'll expand
my dbVehicle table, and then I will expand fields, we can see my fields that I have available in that data source.
And for my VehicleListPage, I can just drag these fields over here onto the grid and that's going to indicate
which fields I want to display on the form and in which order. So let's go ahead and start by dragging the
dbVehicleID over to our grid control. We can see it shows up now here as a string. So I'll continue adding a
few more. Let me go with the VIN number and vehicle type. And I'll go with the make and model. And I'm
using control click to select multiple fields, so you don't necessarily have to drag them one by one. And then
go ahead and add our year onto the form. And we'll add that right after the make and model. And if we want
to move this up, say we want the year field to display on the grid before the make and model, we can simply
highlight the field, we can hold the ALT key and press the up arrow, and it shifts our field up. Each time we
press up, it moves it higher in the order. So that's going to dictate the display order on our grid, on our form.
So that's an overview of how we add controls to satisfy our main design requirement and then we can add
fields to a grid control by dragging them from our data source once we specify the data source property on
our grid. So we've added some fields to hour grid control here on the DBVehicleListPage form. Now we can
go ahead and save all and then we can go preview how our form looks at this point in the development phase.
So I'll switch over from my pattern tab here to the preview tab and we can see now we have my caption, we
have the caption I specified for the specific group control, and then we have our fields here laid out in the
order that we added them to our grid. Just as they appear here. OK. So now, we can go ahead and kind of
repeat these steps for the dbVehicleMaintenance form. Now, this form uses a different form pattern so it's
going to require different controls as we can see here. So let's go ahead and right click and we'll choose new
to begin adding the control for the application bar or the action pane. OK. And if we want, we can go ahead
and add different pieces below this action pane such as an action pane tab and button groups. However, for
this form pattern, it's not required so let's go ahead and meet the requirements first and build out our form
that way. So the next requirement is the details tab. And that is a tab control. So if I right click the design
node, choose new, I can go down till I find my tab. And I can choose that. Now you'll notice this tab control
has other requirements for this particular control. So you have to keep an eye out for the requirements not
only for the high level design pattern but also for each sub-control. OK. So we can see here it's now
highlighted in yellow because it has been added but there's still something that needs your attention. So we'll
go click our tab control and see that this tab control needs to have another tab page added beneath it. So
we'll right click the tab control and we'll choose new tab page. Now, this is the only thing that can be added
beneath the tab control. And again, our tab page control has the option to apply sub-pattern for that control.
OK. So if I click up to my tab control, we can see that these requirements have been satisfied with this
checkmark and I can go back up to my root design node and see that the other requirements have been
satisfied. The custom filter group says none. That means it's OK for this pattern not to have one. And there's a
checkmark. However, we can add one if we wish. Same thing goes for the footer group control. So let's go
ahead and do a save-all again. And we can flip over to our preview tab here and we can see there's this tab
right here. That's a clickable tab page. And as we continue to add more tab pages below this tab control, we
will see more tabs pop up here to the right. So we would go ahead and repeat the process for adding fields
onto these different controls. So for this pattern, we can add a grid somewhere in here, on a certain tab page,
and then we would go ahead and drag our fields from our data sources onto the grid control that would allow
us to display information on this form. So we've added our data sources to our forms and we've got these
form controls set up that go along with our patterns and we've even went ahead and added some fields to our
grid here on this VehicleListPage form. So the last thing we have to do when building our forms is our sub-
patterns. So you can see we have checkmarks next to our three main controls here that say this list page form
pattern is looking pretty good. However, if we go to build this project, we would get an error since this
particular group control here does not have a pattern designated. So what we would need to do is right click
this group control and we'll apply a sub-pattern to it and we can see our only option is the custom and quick
filters because that is the sub-pattern required by this particular main form pattern of list page. So once we go
ahead and apply this custom and quick filters sub-pattern, we can see down in our pattern tab it has updated
with the requirements for this sub-pattern on this control. We need to add a quick filter control. So I can right
click my form group control one. And I'll say new. And I'll go down to quick filter. We can see it adds this
quick filter control beneath my main group control. And now if I click this group control node, and we look in
our pattern tab, everything looks like it's checking out. So we'll go ahead and save this. And now if we were to
go to our other form, the dbVehicleMaintenance form, we can see here that this group control already has
these sub-pattern applied. However, we added this tab page control and this one needs a sub-pattern as well.
So in order to get this to build correctly, we would have to come here, right click this control, and we'll choose
apply pattern and this one wants the tool bar and list sub-pattern. OK. Then we would continue adding these
controls for this tool bar and list sub-pattern. It looks it's missing this grid tree list view table. So we would go
through and keep adding our controls to make sure that our sub-patterns and patterns are having everything
they need to build correctly and ultimately to get our form to work.
Lesson 5: Best Practices
Now let's review some best practices to consider when developing forms. When naming forms, the form name
should match the main underlying table that is the data source. This makes it easier to know where the data is
coming from and it keeps thing uniform in the system. Whenever possible, we should keep the sizing
properties to auto or default to ensure consistent output. Using the form statistic add-in will help give us more
information about the form and the form controls. This also tells us how much of the form's controls are
covered by the chosen pattern. Placing code on forms, a forms method, should be avoided unless it is a last
resort. Codes should typically be placed in a class or table. That way, it can be more easily reused and
customized.

Module Review
In this module, we created some different types of forms to use in our fleet management system. We
discussed how forms are designed and the different types of controls that are used in the creation process. We
added data sources, controls, and elements to the form. Then we chose a pattern to apply and used the
pattern tab to help debug and guide the development process.

MODULE 10 KEY TAKE AWAY


o Form Creation

 Form Controls

 Form Design Layout

 Form.Design

o Root of page

 Group

o General-purpose container control

 Tab

o Control that contains TabPage controls

 TabPage

o Appearance of each TabPage control depends on Tab.Style value

 ButtonGroup

o Special type of Group control that contains buttons

 Action Pane Hierarchy


 ActionpaneTab1

o ButtonGroup1

 Button1

 Button2

 Types of Buttons

 Button

 Command Button

 Men Item Button

 Drop Dialog Button

 Menu Button

 Toolbars

 Toolbar represented by Add, Edit, Map buttons

 Previously known as “Action Pane Strip”

 Grid Styles

 Tabular Style

 List Style

 Simple read only

 Add Elements

 Best Practices

 Name the form to coincide with the main data source table

 Use the “Auto” and “Default” properties for sizing

 Use the Form Statistics add-in for guidance

 Try to cover all controls with the applied pattern

 Avoid placing code on forms


MODULE PRACTICE
Practice 10.1: Create Forms
Scenario

For the Fleet Management System the user interface elements of the forms will need to be created. Following
the standard, there will need to be full entry data pages for both the Vehicle and Vehicle Management tables.
In addition, there will need to be a list page summarizing all of the Vehicles and link to the data pages.

Simon, the developer for Contoso, needs to create a list page form and supporting forms for the Vehicle and
Vehicle Maintenance information.

This practice and the next will cover this scenario.

High Level Steps


1. Create the form
2. Repeat for each additional form
3. Build
Detailed Steps
1. In the Solution Explorer, on the DevelopmentBasicsFMProject Right-click and choose Add
> New item.
2. Under ‘AX 7’ artifacts select User Interface.
3. Select Form.
4. Type “dbfmVehicleDetails” in the Name box and click Add.
5. In the Solution Explorer, on the DevelopmentBasicsFMProject Right-click and choose Add
> New item
6. Under ‘AX 7’ artifacts select User Interface.
7. Select Form.
8. Type “dbfmVehicleMaintenanceDetails” in the Name box and click Add.
9. In the Solution Explorer, on the DevelopmentBasicsFMProject Right-click and choose Add
> New item
10. Under ‘AX 7’ artifacts select User Interface.
11. Select Form.
12. Type “dbfmVehicleListPage” in the Name box and click Add.
13. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
14. Click Build (or use Ctrl+Shift+B)
15. Review the Output screen to review process. Should say “Dynamics AX7 build completed”.

Practice 10.2: Adding Elements


Scenario

This practice is in continuation from the previous practice.


High Level Steps
1. Apply a pattern
2. Add Elements to the form
3. Configure the elements
4. Add a data source
5. Add fields (or field groups)
6. Repeat for each form
7. Build
Detailed Steps
1. In the Solution Explorer, on the DevelopmentBasicsFMProject
2. Find the dbfmVehicleDetails form, right click and click open
3. Right click Design > Apply Pattern > Simple Details w/Toolbar and Fields
4. Right click on the Design | Pattern in the right middle pane, click New and Action Pane.
5. Right click on the Design | Pattern in the right middle pane, click New and Group.
6. Right click FormGroupControl1 > Apply Pattern > Fields and FieldGroups
7. On the dbfmVehicleDetails form, expand the Data Sources
8. Drag and drop dbfmVehicleTable Query from the Simple Queries node to the Data Source of
the form.
9. Right click on the Design | Pattern in the right middle pane, click Properties
10. Data Source = dbfmVehicleTable
11. Title Data Source = dbfmVehicleTable
12. From the Data Sources find the dbfmVehicleTable datasource
13. Expand the field groups under the dbfmVehicleTable node
14. Drag the following groups (in order) to the FormGroupControl1 under the Design node.
15. Action
16. Identification
17. Vehicle Description
18. Click the Save icon.
19. Right Click on dbVehicleDetails under the forms folder in the Solution Explorer select set as
Start up object.
20. Click Start from the menu bar at the top of the page.
21. View new built form that will open in Internet Explorer
22. Close Internet Explorer
23. On the far right of the page, select the Solution Explorer tab to open the Solution Explorer
section again.
24. Find the dbfmVehicleMaintenanceDetails form, right click and click open.
25. Right click Right click on the Design | Pattern in the right middle pane > Apply Pattern >
Task Single
26. Right click Design > New > Action Pane
27. Right click Design > New > Tab
28. Right click FormTabControl1 > New Tab Page
29. Right click FormTabPageControl1 > Apply Pattern > Toolbar and List
30. Right click FormTabPageControl1 > New > Grid
31. On the dbfmVehicleMaintenanceDetails form, expand the Data Sources
32. Drag and drop dbfmVehicleMaintenanceTable Query from the Simple Queries node to the
Data Source of the form.
33. Right click Design > Properties
34. Data Source = dbfmVehicleMaintenance
35. Title Data Source = dbfmVehicleMaintenance
36. From the Data Sources find the dbfmVehicleMaintenance datasource and expand
37. Expand the fields node
38. Drag the following fields (in order) to the FormGridControl1
39. dbfmServiceTypeCode
40. dbfmVehicleID
41. dbfmServiceStartDate
42. dbfmServiceEndDate
43. dbfmEngineDescription
44. dbfmNote
45. Click Save.
46. Right Click on dbVehicleMaintenanceDetails under the forms folder in the Solution
Explorer select set as Start up object.
47. Click Start from the menu bar at the top of the page.
48. View new built form that will open in Internet Explorer
49. Close Internet Explorer
50. On the far right of the page, select the Solution Explorer tab to open the Solution Explorer
section again.
51. In the Solution Explorer, on the DevelopmentBasicsFMProject
52. Find the dbfmVehicleListPage form, right click and click open
53. Right click Design | Pattern and select > Apply Pattern > ListPage
54. Right click Design > New > Action Pane
55. Right click Design > New > Group
56. Right click FormGroupControl1 > Apply Pattern > Custom and Quick Filters
57. Right click FormGroupControl1 > New > QuickFilter
58. Right click Design > New > Grid
59. On the dbVehicleListPage, expand the Data Sources
60. Drag and drop dbfmVehicleTable Query from the Simple Queries node to the Data Source of
the form.
61. Right click Design > Properties
62. Data Source = dbfmVehicleTable
63. Title Data Source = dbfmVehicleTable
64. From the Data Sources find the dbfmVehicle Table datasource
65. Expand, and then expand fields
66. Drag these fields is this order to the FormGridControl1
67. dbfmVehicleID
68. dbfmYear
69. dbfmMake
70. dbfmModel
71. dbfmMileage
72. dbfmGrossVehicleWeight
73. Click Save.
74. Right Click on dbVehicleListPage under the forms folder in the Solution Explorer select set
as Start up object.
75. Click Start from the menu bar at the top of the page.
76. View new built form that will open in Internet Explorer
77. Close Internet Explorer
78. On the far right of the page, select the Solution Explorer tab to open the Solution Explorer
section again.
79. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
80. Click Build (or use Ctrl+Shift+B)
81. Review the Output screen to review process. Should say “Build: 1 succeeded or up-to-date”.
82. Once complete, ensure that the EDTs are synchronized.  Navigate to Dynamics ‘AX 7’ and
click Synchronize database.
MODULE 10: YOUR NOTES
Module 11: Menus
Welcome to Module 11 on menus. We will be covering the creation and application of menus and menu items
for use within the user interface. The objectives for this module are to review how to create and use menu
items. Then we will create menus and attach menu items to them.

Lesson 1: Fleet Management Scenario


Now let's review how menus and menu items will be used for our fleet management scenario. For the fleet
management scenario, we will need to build menu items that point to the newly created forms. We would
build a menu to contain the top-level form, the VehicleListPage. Then we'll link all of the menus using the
menu extension to the existing menu structure of AX. Lastly, we will create menu item buttons for the vehicle
and vehicle maintenance forms.

Lesson 2: Creating Menu Items


In this lesson, we'll review creating menu items. There are three main types of menu items that are used in AX.
The first one is called a display type menu item. This must be used for runnable application objects that
primarily present forms or dialogs to the user. We would attach the menu item type of display to a form for
example. The second menu item type is called output, and this must be used for runnable application objects
whose primary function is to print a result. A good example for using an output menu item type would be an
SSRS report. The third type of menu item is called action. This must be used for runnable application objects
whose primary function is to do some kind of job such as creating or updating transactions in the database,
and this would be linked to a class. Let's review some key property values on display menu items. The first one
is the form view option property. And this specifies which form mode to use when a form is opened from a
menu item. For example, we can have the form opened in the view mode of details view or grid view. There's
also a property value called auto. Next is the normal image property. And this specifies which image will be
used when the menu item is associated with an enabled button control. The open mode property specifies the
view mode of the object. For example, a form can be opened in view only mode or edit mode using this
property. The help text property creates a help string for the menu item. This will be the text that appears in
the status bar when you select the object opened by the menu item such as a form. The label property is
what's displayed in the user interface. For example, it will be the name of the link that appears in the UI which
would launch a formal report. Now let's look at the key property values for the output menu items. The first
one we're going to discuss is the enum parameter. This specifies which enumerated type we want to use as a
parameter for the object that our menu item is linked to. We would then select an enum type parameter which
would be the enum value for that property. These two properties are optional. These properties are typically
used when one form is used in several different situations. You can change the behavior of the form
depending on the enum parameter value. For example, the price disc group form is used by three different
display menu items. Each have a different enum parameter value and the forms in knit method, we would use
a switch construct in X++ which would check the value of the enum parameter and then construct the form
accordingly. The linked permission object property specifies another object such as a form or report whose
permissions are to be applied to this menu item. The linked permission type property then specifies the type
of the object pointed to you by the linked permission object property. Now let's look at the key property
values for action menu item. The first one we're going to discuss is called create permissions. And this
property specifies whether the create permission will be available to select when privileges are assigned to the
menu item. The property values or choices are auto, which means the permission will be available to select as
a privilege on this menu item. If we choose the no property value, the permission will not be available to select
as a privilege on the menu item. The default value for this property is auto. The delete permissions property
specifies whether delete permissions will be available to select when privileges are assigned to the menu item.
The auto value means the permission will be available to select as a privilege on this menu item. The no value
means the permission will not be available to select as a privilege on this menu item. The default value again is
auto. The extended data security property specifies that the menu item appears under all companies instead of
in the context of a single company. The default value for this property is no. The configuration key property
selects which configuration key is required to enable the menu item. Use the key for the module that the
object belongs to. So we've created two forms and we've got our patterns and sub-patterns configured and
our controls set up to get our basic form to display. Now we're going to create two menu items to associate
with each of our forms. Now, to do this, we right click our project, we choose add and new item, and to display
a form, we need the display menu item. And that is located in the user interface group. So I'll choose display
menu item. And the first one I'm going to create is called DBVehicleListPage. I'm going to name it the same as
the form that it's going to open. And when I choose add, again, we get a nice new folder here with our menu
item. It also opens up over here by default in the designer. So when I select it here, I can then begin editing
the properties. And the first property we want to set is the object type. There's a drop down with some
different selections here. For our purpose, we are going to use the form object type. And then the name of
the form. We can use the drop down here to see a list of all the forms. But since we know the name is just
DBVehicleListPage, I'll go ahead and type that and press enter to confirm that that is the string I want. And
then we'll scroll up here under the appearance group and set the label property. This is going to be what
appears in the menu. When the user clicks the menu item and the link, this is the text it's going to display. So I
have this be all vehicles. And I'll choose enter. So now, we have this menu item. It's a display menu item that's
associated with our DBVehicleListPage form. And we can go ahead and repeat that process to add a second
display menu item and associate that with our dbVehicleMaintenance form.

Lesson 3: Creating Menus


In this lesson, we will cover the creation of menus. Menus are prebuilt to include all of the accessible items in
AX from the navigation pane. These are in context to each specific security role and can be modified. So for
example, from our navigation menu here in blue on the left, we can navigate to the cost management menu.
And then we can navigate to the manufacturing accounting submenu within the cost management menu. And
then finally, we can click on one of these menu items here at the end. For example, we can choose production
order and then that would launch some type of form or runnable object from that menu item. Let's take a look
at some of the key property values for menus. The first one is the menu item type. We can specify which type
of menu item we want to associate with this menu. And those we have our three menu item type as options.
That would be display, output, and action. After selecting which menu item type, we can then use our menu
item name property. The menu item name will be filtered based on the menu item type you select. So if we
choose display for menu item type, then the menu item name has to be a display type menu item in the
system. Then we have the configuration key property. And this is used to set which configuration key we're
going to use for the menu. The normal image property specifies which image will be used when the menu is
enabled. And finally, the label property is the UI friendly name of the menu that the user will see in the
navigation menu or submenu. So we've created a menu item and attached it to our VehicleListPage form.
Now, I went ahead and created a second menu item called dbVehicleMaintenance that is linked to the vehicle
maintenance form. So now, we need to place these menu items on a navigational page on a certain menu so
that we can click them in the UI. And for this example, we're going to add our VehicleListPage onto the
organization administration navigational menu page. And to do that, I'm going to go to the Application
Explorer and I'll right click on the AOT node and choose model view. Now, I can see all of the elements in the
system organized within their certain model. And I need to go to the Application Suite model. So I'll expand it.
Then I'll expand the user interface node. And finally, I'll expand the menus node. Now, here we can see all the
different navigational menus in the system. If I launch my client, we can see here there's accounts payable with
these options for submenus. So if I go here, I can see accounts payable with those specific submenus. So it's
set up the same exact way what we see in the UI. Now, for this demonstration, I'm going to scroll down to the
organization administration menu and I'll right click it and I'll choose this option called create extension. And
what that does is create an extension of the organization administration menu item here, or menu page rather,
in my project. I could then right click this and choose open. And it's going to show me again all of these
submenus and the menu items within this menu page. So for this example, I'm going to just expand this folder
here, this submenu called resources and I'll go to my project under my display menu items folder. I'll drag out
my DBVehicleListPage menu item. Again, this is linked to my DBVehicleListPage form. So I'll add it here to the
resources folder. And we'll see it appear here at the bottom of the list. Now I'll go ahead and save this and I'll
go ahead and I'm going to press CTRL SHIFT B for the shortcut key to form a build on my project. When the
build completes, we'll be notified here with the AX build completed. And now we can go check on the UI to
see if these changes have taken effect. So what I'll do is I'll open up my browser page and I'll press F5 to
perform a refresh. And when the page reloads, we'll go ahead and check our organization administration
menu and see if we can find our menu item. So it will load up here in my dashboard page. And I'll go up to
the navigation menu. I'll locate the organization administration page. And then I'll click into the resources
submenu where we added our display menu item. And here it is. I provided a label value of all vehicles for
that menu item so that's what we see here when we click this. So I'm going to go ahead and click it and it's
going to bring up our all vehicles form. And here are the fields that we added to the grid when we were
designing the form as well as our quick filter control. Now, currently, we do not have any data in here. We can
certainly add some by using this new command which would add records into our form grid control here. And
in the next demonstration, what we're going to do is we're going to add a button group here in this gray pane
that's going to allow us to click into our vehicle maintenance form. So it will kind of be set up like a shortcut to
launch a menu item from this button group here instead of from one of the navigational menu pages here. So
we just added our menu item to display our VehicleListPage form to the organization administration menu
page. What we want to do now is add a menu item to act as a button here so that when we click it, it will
launch the vehicle maintenance form from the all vehicles list page form. To do that, we'll go back to Visual
Studio, into the development environment, and we'll open up our DBVehicleListPage form. So I need to add a
button group. And to do that, I'll right click my action pane control. I'll choose new and I'll choose button
group. I'll go ahead and give this button group a caption. We'll call it vehicles. And now, we'll add an
individual button within this group. To do that, I'll right click the button group control. I choose new. And I
choose menu item button. This specifies that this button is going to be linked to a menu item. Now, I'll go
into properties here on my menu item button control. And we have these properties, again, the menu item
type and menu item name. The menu item I want to link to this button is it's dbVehicleMaintenance display
menu item. So to do that, I'll simply type in here my dbVehicleMaintenance. This references the display menu
item called dbVehicleMaintenance. And that's right here in my project. And this menu item is linked to our
dbVehicleMaintenance form. You can see as soon as I do that, the preview pane here for this form updates
with the button I just created. Now, we're free to change the caption here. Or the label. It's used the vehicle
maintenance by default since that's the label value for the menu item. So we'll go ahead and leave that. We'll
save our changes. And we'll perform a build. I'm going to use the CTRL SHIFT B shortcut key. Once the build
has completed, we can go refresh our form and see how our changes took effect. So I'll go back to the form
here in the browser and I'll press F5 to perform a refresh. And once the form loads, we can verify here that our
vehicle maintenance button has been added. Now, if I click this button, it goes ahead and opens up my vehicle
maintenance form. This form is currently blank. We didn't specify any particular grid or any data for this form.
However, we can verify that the link does work correctly.
Module Review
Thanks for joining me in the menus module. In this module, we covered creating menus and extending system
menus as well as associating menu items with menus.

MODULE 11 KEY TAKE AWAY


o Menus

 Creating menu items

 About menu items

 Display

o Used for presenting forms, dialogs and so on

 Output

o Used to print result (reporting)

 Action

o Used to do jobs such as creating or updating transactions

 Key Property Values on Display Menu Items

 Form View Option

o Specifies which form to use when form is opened from a menu item

 Normal Image

o Specifies image used when menu item is associated with enabled button
control

 Open Mode

o Specified view mode for object

 Help Text

o Create help string for menu item

 Label

o Displayed in user interface


 Key Property Values on Output Menu Items

 Enum parameter

 Enum type parameter

 Linked permission object

 Linked permission type

 Key Property Values on Action Menu Items

 Create permissions

 Delete permissions

 Extended data security

 Configuration key

 Creating Menus

 About Menus

 Prebuilt to include all accessible items

 Key Property Values on Menus

 Menu Item Type

 Menu Item Name

 Configuration Key

 Normal Image

 Label

MODULE PRACTICE
Practice 11.1: Create Menu Items
Scenario

For the Fleet management scenario, we will need to build menu items that point to the newly created forms.
Then we will build a menu to contain the top level form, the List page, and then link all of the menus using
Menu Extension to the existing menu structure of AX. Lastly, we will create menu item buttons for the Vehicle
and Vehicle Maintenance forms.

This practice and the next will cover this scenario.

High Level Steps


1. Create a menu item
2. Menu item parameters
3. Create additional menu items
4. Build
Detailed Steps
1. In the Solution Explorer, right mouse click Development BasicsFMSProject.
2. Click Add > New Item
3. Under AX7 Artifacts, Click User Interface
4. Select Display Menu Item
5. Name: dbfmVehicleDetails
6. Click Add
7. Right click dbfmVehicleDetails in the middle pane and select Properties
8. Set the label to Vehicle Details
9. Set Object field to dbVehicleDetails.
10. Right click on dbVehicleDetails under the display menu items folder in the Solution Explorer
11. Set as startup object
12. Click Start on the Toolbar
13. View new built form that will open in Internet Explorer
14. Close Internet Explorer
15. On the far right of the page, select the Solution Explorer tab to open the Solution Explorer section
again.
16. In the Solution Explorer, right mouse click Development BasicsFMSProject.
17. Click Add > New Item
18. Under AX7 Artifacts, Click User Interface
19. Select Display Menu Item
20. Name: dbfmVehicleMaintenance
21. Click Add
22. Right click dbfmVehicleMaintenance > Properties
23. Set the label to VehicleMaintenance.
24. Set Object to dbVehicleMaintenanceDetails
25. Right click on dbVehicleMaintenance under the display menu items folder in the Solution
Explorer
26. Set as startup object
27. Click Start on the Toolbar
28. View new built form that will open in Internet Explorer
29. Close Internet Explorer
30. On the far right of the page, select the Solution Explorer tab to open the Solution Explorer section
again.
31. In the Solution Explorer, right mouse click Development BasicsFMSProject.
32. Click Add > New Item
33. Under AX7 Artifacts, Click User Interface
34. Select Display Menu Item
35. Name: dbfmVehicleListPage
36. Click Add
37. Right click dbfmVehicleListPage > Properties
38. Set the label to VehicleListPage
39. Set the Object to dbVehicleListPage
40. Right click on dbVehicleListPage menu item in the Solution Explorer and Set as startup object.
41. Click Start on the Toolbar
42. View new built form that will open in Internet Explorer
43. Close Internet Explorer
44. On the far right of the page, select the Solution Explorer tab to open the Solution Explorer section
again.
45. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
46. Click Build Solution (or use Ctrl+Shift+B)
47. Review the Output screen to review process. Should say “Build: 1 succeeded or up-to-date”.

Practice 11.2: Create a Menu


Scenario

This practice is a continuation of the previous practice.

High Level Steps


1. Create a Menu
2. Set the properties
3. Extend a Menu
4. Set the properties
5. Build
6. Test in User Interface (Internet Explorer)
7. Update Forms with Menus
8. Build
9. Test in User Interface (Internet Explorer)
Detailed Steps
1. In the Solution Explorer, right mouse click DevelopmentBasicsFMSProject.
2. Click Add > New Item
3. Under AX7 Artifacts, Click User Interface
4. Select Menu
5. Name: dbfmVehicleMenu
6. Click Add
7. Right click dbfmVehicleMenu > Properties
8. Set the label to Vehicle
9. Menu item name: dbfmVehicleListPage
10. In the Application Explorer, expand Application Suite
11. Expand User Interface and expand forms.
12. Select Organization Administration and right click.
13. Click Create extension
14. In the Solution Explorer, right click the OrganizationAdministration.Extention > Open
15. Expand Resources Menu
16. Drag and drop dbfmVehicleMenu from the Solution Explorer under WrkCtrTable.
17. Right click dbVehicleMenu in the middle pane > New > Menu Item Reference
18. Right click MenuItemReference1 > Properties
19. Menu Item Name: dbfmVehicleListPage
20. Name: Vehicles
21. Visible: Yes
22. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
23. Click Build Solution (or use Ctrl+Shift+B)
24. Review the Output screen to review process. Should say “Dynamics AX7 build completed”.
25. Open Internet Explorer that you logged into as part of the prerequisite step and in the UI press
Crtl+F5 to clear cache and refresh.
26. In the Solution Explorer, Open dbfmVehicleListPage
27. Expand Design
28. Right Click FromActionPaneControl1
29. New > Button Group
30. Right Click FromButtonGroupControl1 > Properties
31. Caption: Vehicles
32. Right Click FromButtonGroupControl1 > New > Menu Item Button
33. Right Click FromMenuFunctionButtonControl > Properties
34. Name: Vehicle
35. Menu Item Name: dbfmVehicleDetails
36. Form View Option: Details
37. Big: Yes
38. Right Click FromButtonGroupControl1 > New > Menu Item Button
39. Right Click FromMenuFunctionButtonControl > Properties
40. Name: VehicleMaintenance
41. Menu Item Name: dbfmVehicleMaintenance
42. Form View Option: Details
43. Big: Yes
44. In the Solution Explorer , right click the Solution ‘DevelopmentBasicsFMSProject’
45. Click Build Solution (or use Ctrl+Shift+B)
46. Review the Output screen to review process
47. Open Internet Explorer that you logged into as part of the prerequisite step and in the UI press
Crtl+F5 to clear cache and refresh.
48. Open the navigation pane by clicking the navigation pane button (three lines) at the top right of the
application window.
Navigate to Organization Administration > Resources > Vehicle > Vehicle List Page
MODULE 11: YOUR NOTES
Module 12: X++ Overview
Welcome to Module 12. In this module, we'll give an overview of the X++ programming language within AX.
The objectives for this module are to explore the code editor, to review the controls of the compiler, to create a
runnable class to test code, to review the IntelliSense feature for coding, to introduce variable declaration, to
review basic code syntax, and to identify keywords and operators. Further objectives for this module include to
review the comparison tools for code comparison, to demonstrate how data types are used in code, to discuss
the use of the debugger, and finally, to review code best practices.

Lesson 1: Fleet Management Scenario


In this lesson, we'll review the fleet management scenario for the X++ module. For the fleet management
scenario, we will create a basic class using a static method in order to familiarize ourselves with the coding
process. Special attention in this module will need to be given to the code editor, IntelliSense, syntax, and
code statements in order to complete the future scenarios.

Lesson 2: Code Editor


In this lesson, we're going to review the code editor. X++ is an object-oriented programming language which
consists of three main components. Those are classes, methods, and objects. We will discuss these
components as we go throughout the course. X++ code for a Dynamics AX application is written in the code
editor for Visual Studio. That's what we're looking at here in our screen shot. The standard features that a
developer expects from the code editor are supported. For example, sections of codes are collapsible using
these plus and minuses here on the left-hand side of the code editor. IntelliSense is also a feature that
provides guidance as you write or modify code. It will possible up with suggestions of certain objects. You will
also use the code editor in Visual Studio to write X++ code for your applications. The X++ language is fully
integrated into the Visual Studio environment. You can navigate to methods and classes in the code editor
window using the navigational drop-down menus located at the top of the code editor window. X++ code
runs as .NET CIL. And this comes with many benefits. One of those benefits is that the CIL runs much faster in
many cases. When there are many method calls or algorithmic content, you can expect significant
performance improvements. It's also easier to write application logic in other managed language. AX
assemblies can be consumed directly. The preferred way of consuming business logic in AX is externally using
services. CIL can efficiently reference classes that are available in other .NET assembly DLL files. CIL can also be
operated on by many of the excellent .NET tools available. For Dynamics AX, the X++ compiler has been
rewritten from scratch. No backward incompatible changes have been introduced. An X++ best practice tool
has also been implemented. It allows the addition of user-defined custom rules. The standard compilation
unit for X++ is the same as for other .NET languages like C#. If any method out on an AX model element like a
class or form, fails to compile, the whole compilation fails.

Lesson 3: Create a Runnable Class


In this lesson, we will demonstrate how to create a runnable class which is based on a static main method. To
create a runnable class, we'll need to add the runnable class element type to our project. To do this, we'll right
click our project from the Solution Explorer. We'll choose add, and choose new item. On the left pane under
the artifact group type, we're going to choose code. And the last choice here in the list is the runnable class
element. So we'll select that and we'll give it a name. We'll call it dbHelloWorld. And we'll choose add. Now,
again, it creates a new folder for the new element type of classes. And it opens up by default here in the code
editor. So we have our class named hello world. And then within that, we have this static main method. This is
a method used to test code really quickly. So that's why it's used in the runnable class. Now, in between these
two brackets I'll go ahead and paste in this line of code, which is telling us to display an Infolog with the textual
string message, hello AX world. So I'll go ahead and save this. And what I want to do first is to right click this
class for my project, and I'll choose set as startup object. Now, when I perform my build, it will execute this
specific class. So now, I can go ahead and press CTRL SHIFT B to perform my build. Alternatively, we can right
click the project and choose build. And we'll press the CTRL F5 key to actually run the project. And we'll press
CTRL F5, it performs a build first, and then it goes ahead and runs or executes that startup object. We can see
here our build has completed and we're getting this notification window from Internet Explorer. And we can
open up class runner. And it notifies us here that the class hello world has completed execution and here is the
message from our Infolog. The hello AX world. So that's a quick overview of how to create a runnable class
with a simple output message here in the Infolog. And we'll go ahead and look at some more examples of
code snippets as we go throughout this chapter.

Lesson 4: Intellisense
In this lesson, we will discuss IntelliSense. IntelliSense is a predictive typing tool that aids developers during the
coding process. It prompts the user for known methods and possible choices of elements directly from the
AOT. IntelliSense also helps ensure that items are being consistently used within your code. It also helps
maintain consistent spelling of elements. The features of IntelliSense may vary depending on the version of
Visual Studio that you're running. So let's go ahead and demonstrate a little bit about how IntelliSense works
in the code editor. So I'm here in my runnable class dbHelloWorld that we saw output this hello AX world
message to the Infolog. Now, we can declare some objects to use within our code here at the beginning of our
static void main method. So I'll go ahead and begin typing. If I type the word C-U-S-T for cust, you'll notice
this popup appears with all these different objects in the system. This is IntelliSense kind of predicting what
we're typing. And if we scroll through, we can see there's many different objects. This little grid icon
represents a table. This CustAuditorTemp table. We have a lot of different classes. We also have extended
data types and enums would appear in this list as well. Anything that begins with cust. As I continue to type, it
will continue filtering down the list. So I can see if I typed a T, it recommends the cust table. So we can go
ahead and hit tab or click it from the list. And it will make that selection for us. And then we can go ahead and
give it a reference in our code. So let's see how it works with the base enum. So in our project, we have these
four base enums right now. And if I type DB, you can see it automatically makes that recommendation for the
dbDriveType enum. I'll hit tab to complete that selection. I'll give it an alias or a reference here to use
throughout my code followed by semicolon. And now I can begin using that enum in code. So if I type
dbDriveType, followed by two colons, IntelliSense will show me the values that are available of the different
element values for that enum. We configured this enum to have the following drive types. So when you are
using your base enuming code, you use the double colon to signify you want to choose the value for that
enum. So we can have something like this. Obviously maybe we'd have this in a more complex kind of if
statement to say if our drive type is four-wheel drive, then perform some other logic.

Lesson 5: Data Types


In this lesson, we'll discuss composite data types used in X++ as well as extended data types. We discussed
the different primitive data types available for use within AX in Module 5. The table below is for review.
Composite data types are those that contain other data type constructs. Let's take a look at some of the X++
composite data types. The first is an array. An array represents a list of items of the same data type. For
example, you can have an array that contains ten different strings. The only thing that changes is the index. So
we have an array of index one that references the first element of the array. Containers are a dynamic list of
items containing primitive data types and/or some composite data types. Containers may be a mix of different
data types. A class is a type of definition that describes both variables and methods for instance objects of the
class. This is using classes as data types. Tables can also be used as data types. All tables defined in the
database can be handled as class definitions. We discussed the element extended data types in Module 5.
Extended data types are commonly abbreviated as EDTs. An EDT is a primitive data type or container with a
supplementary name and some additional properties set. For example, we can create a new EDT called name
and base it on not a string, and thereafter, we can then use that EDT and variable and field declarations in the
development environment. When you declare a variable in X++, we use the syntax shown in the following
table. We'll review some of the benefits of using EDTs. Code is easier to read because variables have a
meaningful data type and referenceable name. The properties you set for an ETD are used by all instances of
that type which reduces work and promotes consistency. You can create hierarchies of EDTs which inherit the
properties that are appropriate from the parent and changing other properties as needed. The following code
snippet shows an example of declaring and using an EDT in X++. We have a class called DevBasicsEDTSample.
Within this class, we have a static void method and then we have three lines of code. The first line declares our
EDT, our EDT is a primitive data type string. It's called DBVehicleType in the system. Directly next to it, we
specify an alias or a reference for this DBVehicleType EDT. This is what we're going to refer to as going forward
in our code. In the next line, we set the value of an EDT to the world truck. We then specify to output an info
box and pass through the value of our EDT vehicle type.

Lesson 6: Variable Declaration


In this lesson, we'll look at how variable declaration works in X++. Variables can be declared in small scopes.
This means you can declare a variable within a specific block of code that you're using. This makes things
easier to read. And this concept is known as inline variable declaration. We can also declare variables prior to
using them in an executable statement. They're scoped closer to their use, and therefore, they're easier to find.
The var keyword is available for the compiler to infer the data type. It can be used for declaration of local
variables, but it must be clear for the inferred type and the initialization process. We can assign a value to a
field in line with the declaration. This reduces the amount of code lines and improves the readability of
assignment. In this demonstration, we're going to talk about variable declaration and using the var keyword.
So I have opened my dbHelloWorld class. This is a runnable class, and currently, it's just outputting this
message to the Infolog. So I'll go ahead and paste some new code in. And here, we're using the var keyword
up top at the beginning of our method to declare two variables. The first one is gallons used and the second
one is called miles driven. And you'll notice as I click each one, it highlights them where they appear in the
code below. The var keyword is used to declare a variable that the compiler infers the type. So when I declare
this gallons used variable, I have to instantiate it or give it a value when I'm using the var keyword. So the
compiler knows that this is probably going to be an integer since I'm assigning the initial value of zero to it.
Likewise, with the miles driven variable, I'm instantiating the value to 500. So with the compiler saying, hey, this
looks like an integer, and from then on out, we're going to be using that variable as an integer in our code. So
I've initialized gallons used to zero and miles driven to 500. Then I put a simple division, arithmetic operator
here to divide the miles driven by 25. So essentially, we're dividing 500 by 25 miles per gallon to get me this
gallons used variable. Now, in the Infolog, it expects a string to be outputted within the parentheses.
However, since the gallons used is being inferred by the compiler as an integer, we use the INT2STR which is
the integer to string conversion, and we wrap that in parentheses as well. So it converts this integer value of
gallons used into a string so that we can output it into the Infolog. So I'll go ahead and press CTRL S first of all
to make sure there are no errors. Once you perform a save, if there are any errors in your code, they will be
indicated with the red underline. So since there are no syntax errors or lodged errors, I can go ahead and press
CTRL F5 to perform a build and run this class. So we'll do that. All right. So our build has completed. We can
go check out the class runner. And we can see that the output now is 20, which is the value we would expect.
I'll go back to Visual Studio and I want to note that we can declare variables here at the beginning of our main
method or any method, and we can also declare them in line as we use them throughout the code. If I were to
go down further in the code, I can declare a variable as I type. And we'll look at examples of inline declaration
when we cover while and for loops.

Lesson 7: Key Operators


In this lesson, we'll review the key operators in X++ code. The following table shows some of the different
assignment operators in X++. The first one is the equals sign. This assigns the expression on the right of the
equal sign to the variable on the left. The plus equals operator assigns the variable on the left the current value
plus the expression on the right. The double plus symbol increments the variable by one. The minus equal
sign assigns the variable on the left the current variable value minus the expression on the right. And the
double minus symbol decrements the variable value by one. The following table provides a list of arithmetic
operators that can be used in X++. The first one is what's known as a left shift. And it's represented by two
less than signs in successive order. A left shift is simply a multiplication by two on expression1. So if I had
something like one followed by my left shift operator, and then a four, that means to perform four left shifts on
the value of one which is four multiplications of two. So one times two times two times two times two, which
would output a value of 16. A right shift is a similar concept, expect for it uses a division by two and it's
represented by two successive greater than symbols. The asterisk implies multiplication. So if we had 4*5, the
output would be 20. The forward slash is for division, so if we had 20 forward slash five, the output would be
four. The DIV operator is used for integer division. So it only returns whole numbers based on two
expressions. For example, if I had 100 DIV 21, it would return a four since 21 only goes into a hundred 4 times.
It would have a remainder of 16. However, that value is not returned using the DIV operator. Now, if we use
the MOD operator with the same expression, 100 MOD 21, it would return the value of 16. That's the
remainder from the division. The tilde is a unary operator. And this performs a binary not operation. That
means if we had tilde one, it would give us an output of negative two since it's using binary. The ampersand is
a binary and. So that performs a binary and operation on two expressions. Likewise, the caret represents the
binary XOR operation. And the single bar represents the binary OR operation that performs a binary OR
between with two expressions. And the single bar is usually located under the back space key on most
keyboards. The plus and minus symbols represent themselves where the plus symbol adds expression1 to
expression2. And the minus symbol subtracts expression2 from expression1. The question mark is what's
known as a ternary operator. It takes three expressions. So we can have something like expression1, question
mark, expression two, colon, expression three. That means if expression1 is true, it will return expression2.
However, if it's not, expression three will be returned. Now let's look at a table of relational operators that can
be used in X++. The first one is the like operator. This returns true if expression1 is like expression2. The like
operator can also use an asterisk as a wild card to represent zero or more characters or a question mark as a
wild card for one character only. For example, we can have something like if vehicle ID like one asterisk, then
perform some logic. That would return true if the vehicle ID simply began with the number one. If we used if
vehicle ID like one question mark, that would only return true if there were only like two characters. If there
was like 10 or 11 or 12, something that began with a one had another character after it. The exclamation mark
is the not operator. It's a negation operator that can be used in front of a field or table or a statement. The
exclamation point equal sign is the inequality operator and it means if expression1 is not equal to expression2.
The hash tag or pound sign symbol represents a prefix on macro names. So that indicates that a macro is
being run and macros are found under the code node in the Application Explorer. The double ampersand
represents the logical and. If expression1 and expression2 are true, we use the double ampersand. The logical
or is represented by two bars. So we can have expression1, double bar, expression2, and that simply means if
either of those is true, go ahead and proceed with the rest of my if statement. The less than sign is represented
by the less than symbol. Likewise, the greater than symbol is represented by the greater than symbol. To
determine equality, we use the double equal sign, and that returns true if both expressions on either side are
equal. The greater than or equal to symbol is represented by a greater than sign followed by the equals sign.
So we can say if expression1 is greater than or equal to expression2, proceed with some other logic. The order
of operator precedence is very important when determining how things will be executed in your code and
ultimately helping you achieve the output that you want. The order is indicated by this table with the first one
being the unary operators. Those are things like negation. The second order is the multiplication, the left and
right shifts, and the bit wise or binary and. We also have the bit wise exclusive or. The third order of operation
is additive which is subtraction and addition. Or the bit wise binary inclusive or which is represented by the
single bar here. The fourth thing to be executed is the relational or equality operators. And those are things
like greater than, less than, equal to, like, or the not equal to symbol. Fifth is the logical operators and and or.
The double ampersand representing the and, and the double bar representing the or. And lastly is our
conditional. This is the true unary operator of the question mark and the colon that's associated with those
expressions.

Lesson 8: Basic Syntax - Part 1


So now let's overview a little bit more on the basic syntax of using X++. In Visual Studio, the methods start
with a one-tab indentation. Everything within the method starts with a two-tab indentation. The starting
parenthesis on method declarations and calls should be the character just after the method name. If there are
one or two parameters, the parameters can be listed on the same line. However, if there are more than two
parameters, we should move each parameter onto a new line and indent by four spaces to keep things
readable and clean. Some other considerations to consider when using syntax are to only have one statement
per line. You should break up complex expressions that are more than one line just to make it visually clear
and easier for people to read. You should use a single blank line to separate entities. Do not use parenthesis
around the case constants. And do not use parenthesis around where expressions. Add one space between if,
switch, for, while, and the expressions starting parentheses. Use braces around all code blocks expect for
around case clauses in a switch statement. Use braces even if there is only one statement in the block. There
are three main types of basic output that we can create from our code. The first one is what's known as a box.
Next, we have an Infolog, and finally, we have a dialog button. Let's take a look at some syntax for utilizing a
box type output as well as an Infolog type output. In the first example, we're using the box keyword followed
by two colons and then the word info. And then in parentheses, we have three different text or stream
parameters we can enter. The first one is what's going to be contained in the body of the message box
followed by a comma and then the second string which is going to be what text appears in the title of that
message box. And finally, we have what we want to display as the help text in that message box. Another type
of box output is called the warning box. And again, this uses parentheses to enclose three different types of
streams separated by commas. Similar to the info box, we have this warning box and it uses the first parameter
as the body text for the warning box. Then we have the warning title, followed by the help text for that box.
Next we have the Infolog. This is the second output type we're going to discuss. To use an Infolog output, we
simply use the info keyword and then in parentheses, we enclose a certain sentence or string in quotations.
We can also pass through variables within the info keyword. We then have the warning Infolog message type.
And again, it's a similar syntax. It's just a sentence or variable. And if we use a textual sentence, we enclose
that in quotation marks to indicate the beginning and ending of that sentence. And finally, we have the error
Infolog. This is using the error keyword. And then again, we follow the same syntax with the parentheses and
quotations around our string or sentence. The third type of output syntax we're going to discuss is what's
known as a dialog. And in the code here, we're instantiating and creating a dialog button object and then
we're setting the value to be a yesNoCancel box. And a yesNoCancel box contains three buttons. The yes
button, the no button, and the cancel button. And within parentheses here, we're specifying what to contain in
the body of the box and then how to handle the situation where the dialog button yes is chosen. So let's take
a look at some of the different types of conditional statements and loops in X++. You can specify conditions
under which a block of code must be executed or skipped. Each conditional test evaluates to either true or
false. The first type of conditional statement we're going to look at is called an if statement and an if else
statement. This evaluates a question or a condition and executes a statement or a set of statements if the
condition is true. You can provide an alternative statement or set of statements that are executed if those
conditions are false. That would be handled by the else statement. A switch statement is a multi-branch
language construct. You can create more than two branches by using the switch statement. This is in contrast
to the if statement. You have to nest statements to create the same effect when using an if statement. The
next type of loops we're going to discuss are repetitive constructs in X++. X++ has three types of loops. The
first one is called a while loop. This enables you to repeatedly execute one or more statements as long as a
condition is true. The statement is executed from zero to many times, depending on how many times the
condition is met. A do while loop is similar to the while loop in the way it loops over repetitively. However, it's
always executed at least one time, whereas a while loop does not have to be executed at all if the initial
condition is not met. Lastly, we have a for loop. This is similar to the while loop as well, only there's an initial
value to control the variable, and you can increment or decrement that value to handle the flow throughout the
loop. Two types of conditional statements that we're going to discuss are the if else statement and a switch
statement. And these are both used to answer a question or check a condition and then perform some logic
depending if that condition is true or false. So in the left pane, we're going to analyze an if else statement.
And then in the right side, we're going to check out a switch statement. So I'll go ahead and begin on the left
with the if else statement. Now, here we're initializing an integer variable called oil change and setting it to an
initial value of three. Our if statement begins with the if keyword and then in parentheses, directly next to it,
the condition we want to check. So we're saying, if the oil change variable is bigger than or equal to two, then
go ahead and execute whatever is between these two brackets beneath the if statement which is this Infolog
message of a repeat customer. If this oil change greater than or equal to two is not true, then we'll go
immediately to our else statement and skip all this logic here. So then it executes what's between the brackets
and the else statement which is an Infolog message displaying new customer. For the switch statement, it's
slightly different but uses a similar kind of checking of conditions. So here, we're initializing again an oil
change integer variable three and we're also initializing a string variable called answer. And answer we're
going to use to output ultimately at the end in our info box, depending on which case is true in our switch
statement. The switch statement begins with the switch keyword followed by a variable or condition in
parentheses, and we're simply sending through that oil change variable which has a value of three. And then
enclosed in all the brackets are case scenarios. So case where the variable being passed in is one followed by
the colon and then if that case is true, we execute this code. If case where it's two is true, we execute this code.
Otherwise we execute our default case which is this little block of code. So the default kind of switch here is
similar to an else statement which says if case 1 and case 2 are not true, execute the default statement. So we
know that an oil change variable is not one and it's not two. Therefore, it would execute the default statement
which sets our string variable answer to frequent customer. We then break from the code and output that to
an Infolog. Two commonly used types of loops in X++ include while loops and for loops. On the left-hand
side we have an example here of a while loop. On the right-hand side we have a code snippet for an example
of a for loop. So we'll begin in the left and discuss this while loop here. At the very beginning, we're initializing
an integer variable called counter1 to a value of zero. We then use the while keyword to initialize a while loop
and a parentheses is the condition to evaluate that loop under. So this while loop will continue going until the
counter1 variable does not equal -- will continue going while the counter1 variable is not equal to four. As
long as counter1 is not equal to four, the code within the brackets will be executed here. These two lines. And
what they're doing is displaying an Infolog with the variable of counter1 which has been converted from
integer to string for the purposes of displaying it in the Infolog message and then we're incrementing the
counter1 variable by a value of one using the ++ operator. So this while loop would go through several times
until the counter1 reached four at which this condition is no longer true and it would stop executing. So it
would go through once with the counter1 variable zero, then it would go through again, incrementing it by
one, the counter1 value is now one, and it would keep going, and once it hit four, the while loop would stop.
So this Infolog would print each time in the loop until that counter1 variable hit a four. In the four loop
example, it's very similar exempt for we have three conditions in the parentheses, and we use a keyword four,
and then within our parentheses, we have three different pieces and the first piece is where we initialize our
counter variable. So we're again specifying an integer variable called counter2 and we're setting the value to
zero. Then we have our semicolon, and the second piece within a parentheses is the condition to evaluate the
four loop under, which is the same as the condition here for this while loop. We're continuing this loop while
the value of counter2 is not equal to four. And then the third piece is how we're incrementing our counter
variable and we're using again the ++ operator which increments it by a value of one. And then we go ahead
and execute the code within the brackets here which are these two lines. So it's going to output an Infolog
that says counter2 is, and then this percent one is actually replaced by the variable counter2. So you'll notice
we have this quotation mark which is a string followed by a comma. And after the comma, that very first
variable is substituted in the percent one piece here in the output. So it would keep outputting this info
message again multiple times looping through the four loop until that counter2 does not equal the four
condition has been met. At which point the loop will stop executing.

Lesson 9: Basic Syntax - Part 2


Let's take a look at how the if else statement works in our runnable class. So I've gone ahead and pasted the
code from our slide directly here into our runnable class. I'll press CTRL S which performs a save and also
checks our syntax and logic to make sure there are no errors. So this code looks good to go. There were no
red underlines or errors, and now I can go ahead and press CTRL F5 to perform a build and we can see how the
output would look. So go ahead and do that. All right. So our build has completed. I'll now open up my
browser window for the class runner to verify the output, and here we can see we have a message of repeat
customer. Now, if we jump back into the code, we can see that our oil change variable is three. And this
condition here, if it's greater than or equal to two, can display the repeat customer message has been met. So
that's why we're seeing that message. OK. So now let's go ahead and demonstrate an example of a switch
case. So we'll use the same code snippet from our slide. And we'll paste it in here. And I'll go ahead and use
the CTRL S keyboard shortcut to ensure there are no errors in the code. And I'll try to tab things over to keep
things lined up with our cases here. OK. So now we can go ahead and use CTRL F5 to build this and verify the
output. All right. So our build has completed. If I verify my class runner output, we have a message of
frequent customer. Now I'm going to flip back to the code in Visual Studio and we can see that our switch
case on the oil change variable which has a value of three met the default case here where answer was set to
frequent customer and then outputted to us in the info message. The case one was not true because oil
change is equal to three. And case two is not true because oil change again is equal to three and not two. So
we had to output based on the default case which handles every other scenario where the oil change is not one
or two. In this example, we're looking at a code snippet for a while loop. And this is the same code snippet
from the slide that we discussed. And I'm using my runnable class again as a basis to paste this code into a
static void main method which is set as my project startup object, which I execute by pressing CTRL F5. Now,
this while loop again, we're initializing a counter variable of called counter1 and setting it to zero. And then
we're executing the while loop as long as that counter1 variable does not equal four. As soon as it equals four,
this condition is no longer true and, thus, the loop will stop executing. And we increment our counter variable
by one each time the loop goes through. So let's go ahead and press CTRL 5 to perform a build and run our
class here and verify the output. So our build has completed. We can go ahead and verify the results by
launching the class runner window. And we can see here on the info output it has a value of three. However, if
we go to the right, it's telling us there are four different outputs with a down arrow. We can click that and we
can see we have zero outputted, then we have a next line with the value of one. The next output has two and
the final output has three. We have four results from that loop. It went through the loop four times, first on
the value of zero, and as we incremented our counter variable, it continued to execute and print these lines
until it reached the value of four, at which point it did not enter the loop and, therefore, we do not see the
value of four outputted in our messages here. In this example, we're looking at a code snippet for a for loop.
Again, this is the same piece of code from our slides that we discussed. And I've pasted this for loop here into
my static main method in my runnable class called dbHelloWorld. And what I want to do first again is press
CTRL S. This performs a save. It's the same thing as clicking this little disk icon here. And the save also goes
through and checks for any syntax and logic errors that we need to be made aware of before we can run this
class. So it's looking good. There are no errors. Again, to run this, I'll go ahead and press CTRL F5. And it will
perform a build and execute this class. So again, we can verify that our build has completed. And if I go to the
Internet Explorer, I'll see my class runner window that has executed this for loop. And again, we have this drop
down arrow which indicates there are four more messages. Currently it only displays three at a time so we
have to use the scroll bar to make sure we can see all of them. And the output is counter to zero for the first
line. Then it continues. Counter2 is one. Counter2 is two. And counter2 is three. So it's similar to the output
from our while loop in the sense that it outputted the values of zero through 3 and stopped the execution as
soon as the value of four was hit for the counter variable and does not therefore print the value of four. Now,
we noticed this one includes the text counter2 is. We can go back to our code and see that in our Infolog
where we're sending out this sentence that says counter2 is. And again, this percent one is replaced by the first
variable after the comma. If I were to go in here and type something like also percent two, and then I placed a
comma after this counter2 variable, and if we had another variable declared, you know, counter3, for example,
this value for counter3 would then be outputted here in place of percent two since it's the second value or the
second variable after the commas. So that's something to keep in mind when outputting using the Infolog
format.

Lesson 10: Comparison Tools


In this lesson, we will discuss comparison tools which can be used to compare different pieces of X++ code.
When using comparison tools, you have the opportunity to have the original code in the left pane, the new
code in the center pane, and the merged code in the right pane. You can then interact with all three. To install
the comparison tools, it is required to have source control both configured and installed. In addition, there are
Visual Studio extensions that can be installed for comparison. If you are developing using overlayering, you
can also use comparison tools to compare the code in different layers. Refer to MSDN for the version of Visual
Studio that you are operating for both the extensions and command line options to compare code versions.

Lesson 11: Debugger


In this lesson, we will learn about how the debugger works in AX. To debug X++ code in AX, you will use the
debugger in Visual Studio. The debugging process is similar to debugging any other application created with
Visual Studio. For example, the standard tools for examining the application are available when your code is
stopped at a breakpoint. To debug X++ code, we would use the following procedure. In Visual Studio, we
would open the X++ code that we want to debug by right clicking any code element from our project and
choosing open. We could then locate a line or lines where you want execution to stop and set break points in
those lines. And in the screen shot, a breakpoint is indicated by this red dot here and we can simply click in
this gray pane on any line, and it will insert a breakpoint at that line in code. We can also press F9 when the
cursor is on a specific line to insert a breakpoint. We would then save the code and right click the code
element again and choose set as startup object, and then we go ahead and press CTRL F5 to build and run the
code with the breakpoint set. On the debug menu, we can click start debugging. It's important that you run
the application this way. Otherwise, the program will not stop at your breakpoints. In the application, perform
the action that causes the code you are interested in to run. Typically, this would be an action like displaying a
form. We can use the tools in Visual Studio to examine the application. For example, we can hover the pointer
over certain variables in our X++ code to see their values. We can also use commands from the debug menu
to step through the code. Tools like the autos window in Visual Studio will show important information about
the state of the application. Another tool specific to debugging is called the Infolog. Frequently, info
statements are added to code to log status messages as the application is running. You can view these Infolog
messages directly within Visual Studio as well. We can go to the view menu and choose Infolog to bring up
this Infolog box. After you have finished debugging the application, close Dynamics AX and Visual Studio will
exit debugging mode.

Lesson 12: Best Practices


In this lesson, we'll review some of the best practices to keep in mind when coding. The X++ compiler checks
the code for best practice issues. These issues can result in best practice errors, warnings, or informational
messages. Best practices involve understanding all of the things that you should do and distinguishing them
from the things that you can do. Best practices ensure consistency throughout the code which allows other
developers to more easily read and understand your code. They also make the code more secure and ensure
there is no redundant code. Upgrading becomes easier and quicker and has less risk of errors if best practices
are properly followed. Naming conventions contribute to consistency and to making the application easier to
understand. Where possible, application object names should be constructed hierarchically from three basic
components: the business area name, the business area description, and the action performed for classes or
the type of contents for tables. All names shuck in U.S. English, and the default rule is to use logical and
descriptive names if no other specialized rules apply. Identifier names have a limit of 40 characters. Names in
the Application Explorer and X++ code must correspond to the names in the U.S. English user interface.
Names should always be spelled correctly and used consistently. Each path in the AOT must be unique so
nodes cannot have identical names. Do not begin a name with AAA or copy of. And do not begin a name with
DEL underscore unless it's a table, extended data type, or enum that is needed for data upgrade purposes.
Placement of code is dependent on the code you're writing. The preferred procedure in an object-oriented
programming language is to place the code in a class that can be reused and called whenever it's needed.
Placing code in classes enables greater control over where the code is executed. Performance considerations
often dictate where code should run, and so having control over this is desirable. Code placed in forms always
runs on the client which may, therefore, cause a lot of client server communication. Always place the code
nearest to the source so it can be more easily manipulated. For instance, code that manipulates a table should
be placed in that table's methods. Best practice is to place as little code as possible on forms. A best practice
for all programming is the use of comments. It is important when developing X++ programs in AX to use
comments and document what the code does and how parameters are used. It's also good to know who made
the changes, when and why. When upgrading code, you need to decide whether to merge code and, if so, how
to merge it. Therefore, comments are very useful to help determine why the code change was made. You can
insert comments directly into code lines. Comments are ignored by the compiler and they turn green in the
code editor. To insert a comment, we use two forward slashes. We also have to-do comments which are
indicated by the TO-DO keyword. That's T-O-D-O in all caps. We also want to make sure our variable
declaration are in scope and that the code is placed nearest to the source that we are using. Finally, header
comments are used by using three forward slashes usually at the beginning of a class or method to indicate a
general idea of what's going on within that class.

Module Review
In this module, we explored the code editor and created a runnable class. We then previewed how IntelliSense
works and introduced variable declaration. Next we reviewed basic syntax, keywords, and operators to use in
X++. We then discussed comparison tools and using the debugger in Visual Studio. Finally, we examined the
best practices to use when coding.

MODULE 12 KEY TAKE AWAY


o X++ Overview

 Code Editor

 Visual Studio Environment

 Uses X++ code

 Benefits of X++ Code and .NET CIL

 CIL runs much faster in most scenarios

o Easier to rewrite application logic in other managed languages

o Dynamics AX assemblies can be consumed directly

o Preferred way of consuming business logic in Dynamics AX externally is by


using services

 CIL can efficiently reference classes that are available in other .NET assembly DLL
files

 CIL can be operated on by .NET tools

 Compiler

 Has been rewritten from scratch

 No backward-incompatible changes introduced

 X++ best practice tool has been implemented

 Allows addition of user-defined custom rules

 Standard compilation unit for X++ is same as other .NET languages, i.e. C#.
 IntelliSense

 Predictive typing tool of the elements directly from the AOT

 Prompts the user for known methods and possible choices

 Ensures that items are consistently used

 Helps maintain consistent spelling of elements

 Varies with version of Visual Studio

 Data Types

 Primitive Data Types

 Anytype

o Placeholder for any data type

 Booleans

o Can only contain the values false and true

 Dates

o Contains day, month and year

 Enums

o Abbreviation for enumerated text – a set of literals

 GUIDs

o Global unique identifier

 Integers

o Number without decimal point.

o Use keyword int

 Reals

o Numbers with decimal point

 Strings
o Number of characters

o Use keyword str

 TimeOfDay

o Contains hours, minutes, and seconds

o Use system type timeOfDay

 Utcdatetime

o Contains year, month, day, hour, minute and second

 Composite Data Types

 Arrays

o List of items with same data type and name

 Containers

o Dynamic list of items containing primitive data types

 Classes as Data Types

o Type definition that describes both variables and methods

 Tables as Data Types

o All tables defined in the data base can be handled as class definitions

 Extended Data Types

 User defined types

 Additional name and properties

 Declaration and syntax to the left

 Benefits of EDTs

 Code is easier to read because variables have meaningful data type

 Properties set for EDT are used by all instances of that type, reduces work and
promotes consistency
 Can create hierarchies of EDTs inheriting the properties that are appropriate from
the parent and changing other properties

 Variable Declaration

 Declare in small scopes

 Easier readability

 Is within the block of code that you’re using

 Declare prior to using in executable statement

 Scoped closer to use

 Easier to find

 Var keyword is available to infer the type

 Used for declaration of local variables

 Must be clear for inferred type in initialization

 Assign value to field in line with the declaration

 Reduces code lines

 Improves readability of assignment

 Key Operators

 Assignment operators

 =

o Assigns expression right of equal sign to variable on left

 +=

o Assigns variable on left to the current variable value plus expression on


the right

 ++

o Increments the variable by one

 -=
o Assigns the variable on left to the current variable value minus expression
on the right

 --

o Decrements the variable by one

 Arithmetic Operators

 <<

o Left Shift: performs expression2 left shift on expression1

 >>

o Right shift: performs expression2 right shift on expression1

 *

o Multiply: multiples expression1 by expression2

 /

o Divide: Dives expression1 by expression2

 DIV

o Integer divison: Performs an integer divison of expression1 by expression2

 MOD

o Integer remainder: Returns remainder of an integer divison of expression1


by expression2

 ~

o Not: Unary operator. Performs a binary not-operation

 &

o Binary AND: performs binary and-operation

 ^

o Binary XOR: performs binary XOR-operation

 |
o Binary OR: Performs binary or-operation

 +

o Plus: adds expression1 to expression2

 -

o Minus: subtracts expression2 from expression1

 ?

o Ternary operator: Takes three expressions. If expression1 is true,


expression2 is returned; otherwise, expression3 is returned

 Relational Operators

 Like

o Returns true if expression1 is like expression2

 !

o Not

 !=

o Inequality operator (not equal to)

 #

o Prefix on macro names

 &&

o Logical AND.

 ||

o Logical OR

 <

o Less than

 ==
o Returns true if both expressions are equal

 >

o Greater than

 >=

o Greater than or equal

 Order of Operator Precedence

 Unary operators

o –

o ~

o !

 Multiplicative, shift, bitwise AND, bitwise exclusive OR

o *

o /

o %

o DIV

o <<

o >>

o &

o ^

 Additive, bitwise inclusive OR

o +

o –

o |

 Relational, equality
o <

o <=

o ==

o !=

o >

o >=

o Like

o As

o Is

 Logical operators (AND, OR)

o &&

o ||

 Conditional

o ?:

 Basic Syntax

 In Visual Studio methods start with one tab

 Everything within method starts at two tabs

 Starting parenthesis on method declaration and calls should be the character just after
the method name (no space).

 If there are one or two parameters, the parameters can be listed on the same line.

 More than two parameters, move each parameter onto a new line, and indent by 4
spaces

 Only one statement per line

 Break up complex expressions that are more than one line – make it visually clear

 Use a single blank line to separate entities


 Do not use parentheses around the case constants

 Do not use parentheses around where expressions

 Add one space between if, switch, for, while and the expressions starting parentheses.

 Use braces around all code blocks, except for around case clauses in a switch statement

 Use braces even if there is only one statement in the block

 Basic Output

 Create a box

 Create an Info log

 Create a dialog button

 Supported Statements and Loops

 If and if…else

 Switch

 While

 Do while

 For

 Comparison Tools

 Old code = Original

 New code = Import

 Merged code = Results

 Debugger

 Debugging in Dynamics ‘AX 7’ Preview requires Visual Studio.

 Infolog

 Autos window

 Shows important information


 Best Practices

 Naming Conventions

 Code Placement

 Comments

 Variable declaration within scope

 Header comments using ///

MODULE PRACTICE
Practice 12: Create a Runnable Class
Scenario

For the fleet management scenario, in the X++ code review we will need to create a static method in order to
familiarize ourselves with coding. Special attention in this module will need to be given to the code editor,
intellisense, syntax, and code statements in order to complete future scenarios.

High Level Steps


1. Create a class
2. Input code
3. Set as startup object
4. Build
5. Test
Detailed Steps
1. In the Solution Explorer, right click DevelopmentBasicsFMSProject
2. Add > New Item
3. Under AX7 Artifacts, select Code
4. Select Runnable Class
5. Name: dbfmFleetManagementWelcome
6. Click Add
7. Type:
i. class dbfmFleetManagementWelcome
ii. {
1. public static void main(Args _args)
2. {
3. info("Welcome to the Fleet Management Module");
4. }
iii. }
8. Save.
9. In the Solution Explorer, right click dbfmFleetManagementWelcome > Set as Startup Object
10. Click Start
MODULE 12: YOUR NOTES
Module 13: Classes
Welcome to Module 13 on classes. In this module, we will review the structure of classes as well as creating
and using classes. The objectives for the classes module are to review the structure of classes, to demonstrate
the use of methods within classes, to create a base class, and then to review the concepts behind class
inheritance, to create an inherited class, and finally, to review the best practices for classes.

Lesson 1: Fleet Management Scenario


In this lesson, we will review how we're going to use classes for our fleet management scenario. For the fleet
management scenario, we're going to create a class to insert vehicles in a quick entry process. In addition,
we're going to create a class that extends the base class and allows for the quick entry of trucks.

Lesson 2: Class Structure


In this lesson, we're going to review the basic structure of a class. A class is a software construct that defines
the data and methods or behavior of the specific concrete objects that are subsequently constructed from that
class. It can be thought as a blueprint or a set of instructions for different instances of an object. It is possible
for multiple instances of the object to exist and for each instance to hold different values in its variables and,
therefore, to run differently. Instance methods are embedded in each object that is created from the class and
can perform some type of action such as a calculation and then returning a value. Methods can be seen as a
work order on these set of instructions. They help construct the house from the blueprint which is the class.
We then have usable code. Variables are the data for the class. Variables and X++ classes are specific to an
object. That is, every object constructed from the class declaration has its own copy of the variable. Such
variables are known as instance variables.

Lesson 3: Create a Base Class


In this lesson, we're going to create a base class which can then be inherited by another class. In the last
module, we created a runnable class. And the runnable class, by default, includes this public static void main
method for us where we can put some code and run it. In this demonstration, we're going to create a normal
class. And we're going to use this class as a base class that can then be extended further as we develop our
fleet management system. So to add a normal class, we simply right click our project from the Solution
Explorer. And we choose add and then we choose new item. From the code element type, we have four
options. Before we chose this runnable class, now we simply will choose the class element. And we'll call this
dbfmVehicleEntry. And then we can choose add. And now, we have a blank class. We have a class name and
then our brackets where we can begin adding different code and methods.

Lesson 4: Methods
In this lesson, we will review methods. Method declarations consist of a header and a body. The method
header declares the name and return type of the method. The return type could be void which indicates that
there is no value being returned from that method. The method header also contains parameters and method
modifiers. The method body consists of variable declarations, method declarations, and code statements. Let's
review some of the main types of methods. A class declaration specifies the name of the class and the
necessary variables. It can also specify if inheritance is going to be used. Instance methods or object methods
are embedded in each object that is created from the class. They are called by using the syntax
objectname.methodname, and then followed by parentheses. You must instantiate the object before you can
use the method. Static methods are also known as class methods. And they belong to a class and are created
by using the keyword static. They are called by using the syntax class name colon colon method name and
then the parentheses. You do not need to instantiate an object before you use static methods. Static methods
are widely used in AX to work with data that is stored in tables. And lastly, we have main methods. A main
method is a class that is executed directly from a menu option. A good example of this is the static void main
methods we've been using in our runnable classes. The method should only create an instance of the object
and then call the necessary member methods. The underscore arch parameter allows you to transfer data to
the method. So I've added some code to our dbfmVehicleEntry base class that we created earlier in this
module. This code creates a dialog box or a quick entry kind of form that takes a user's input values and uses
them to insert data into the underlying table, so that eventually we can see that data on our VehicleListPage
form. So let's go through this code and see what's going on. We have our class called dbfmVehicleEntry. At
the beginning, we're creating a dialog object and we're creating dialog fields. Three of them. And then we're
also instantiating our dbVehicle table and giving it the reference called vehicle table. We have several methods
within this class. The first one here is the void method of main. Now, the main method instantiates our class
dbfmVehicleEntry and we're giving it a reference of a new name called VehicleEntry to be used within our code.
And then we set an equal to and we use the new operator which tells us to go instantiate a new instance of our
class, dbfmVehicleEntry, and then we call our class VehicleEntry.run. So we're calling the run method on our
own class here. So if we go down to the run method here on line 23, we can see it's a public method of type
void. The void indicates it does not return a value. It's just performing some logic here. We will discuss what
the public keyword means in the best practices lesson on this module. It's essentially a scope, so we're saying
that the variables and methods within this particular method can be accessed by outside classes and methods.
So the first thing this run method is doing in our class is calling another method called setupDialog. We use
this keyword to reference that the setupDialog method is in this class. So we call this .setupDialog. And our
setupDialog is located right here, and this method is also void, which means we're not returning any values.
What the setupDialog does is create the dialog box, the dialog window. And we have these three different
dialog fields that we created up here. They are all of the object type dialog field, simply with different names.
So we have three dialog fields, one for the vehicle make, one for the vehicle model, and one for the VIN
number. Now, we're using the dialog.add field and we're calling -- we're using the extended type of string. So
we're saying these DB VIN, make and model feeds are not extended data types of string. After the comma,
we're specifying what to put them -- what label value to supply for the dialog window for each of these fields.
So again, the field in parentheses is our actual field that we're using from our table, the DB make, the DB
model, and the DB VIN. OK. So if we go back to our run method, we'll continue walking through this step by
step. We have the dialog.run method which now runs our dialog. We have our three fields created on that
dialog window. And then we have the dialog.wait method which causes us to wait until we receive the user
input. Then we execute an if statement to say once the closed or OK button was chosen on the dialog, to go
ahead and execute this logic. So when the dialog has been closed and the values have been supplied, we call a
method called getFromDialog. And that method is right here. It's also a void method. Now, the
getFromDialog method, we're creating three string values within our code, make, model, and VIN, and we're
setting each of those to be equal to the value typed in on the dialog box in each of the respective dialog fields.
We then set our vehicle table buffer variable fields to be whatever the user typed in here in the dialog box.
And then when we go back up to our main method, or our run method, after the getFromDialog, the next line
of code is VehicleTableInsert. So then, we have these values passed in the dialog box. They've been assigned
to our buffer variable, our vehicle table, and now we're going to insert them with the vehicle table that insert
method command. And this is the insert method on the table. OK. So that's a quick walk-through of what
these different methods are doing. Let's go ahead and press CTRL F5 to run this and see how the dialog.entry
form works. So I'll go ahead and press CTRL F5 to build and run this class. Keep in mind, I have set this as my
startup class, or my startup object, so that when this project builds and executes, we will see the output from
this particular class. OK. So we verify that our build has been completed here. And we can go ahead and open
up our class runner window. And here, we have our quick VehicleEntry form with our three dialog fields that
the user can type in, supply values, and choose OK. And that's ultimately going to insert them into our vehicle
table. Now, we can see here in this void new method, we're setting the new dialog and then we're supplying
the label here and that's where we get in heading from. So let's go ahead and type some information in this
dialog box. Now, here, I have our VehicleListPage pulled up in the UI. I went ahead and just entered in some
random data here, just to give us something to look at. Then when we supply some values here on our dialog,
we should be able to see those appear then on our VehicleListPage. OK. So let's go ahead and just make up
some information, so we'll call this a Lincoln, and we'll call this an MKX. And we could just make up a number
for the VIN, and let's go ahead and hit OK. All right. Now, when we come to our list page over here and
refresh it, we should be able to see that record we just typed in the dialog be visible. OK. There it is at the
bottom of the table, we typed in Lincoln MKX. And this particular form actually does not show the VIN.
However, if we had that set up, then we would also see that value.

Lesson 5: Class Inheritance


In this lesson, we will review how class inheritance works. Inheritance is a concept where one class can inherit
all of the methods and variables from another class. A child class inherits the methods of the parent class.
Additional methods can be applied to the child class, and inherited methods can be overridden, this means
that the child class is not always identical to the parent class. The advantage of inheritance in object-oriented
programming is that code can be written one time and then reused many times. To have a class inherit from
another class, we modify the class declaration code of the child class by appending the extends keyword and
then the name of the parent class. So we can have something like class, child class name extends parent class
name. Objects created from the child have the same methods and variables as the parent. Objects created
from the child may have methods and variables that do not exist in the parent. And finally, objects created
from the child may have methods from the parent that are overridden or altered in some way within the child
class. Let's take a look at an example of class inheritance. Suppose we have a parent class called InventType.
And suppose we have a child class called InventTypeCustom. This parent class is what's known as the base
class and the child class would be inheriting from or extending that base class. Suppose we also have three
methods within our parent class called InventType. They are canInventBeReserved, palletTagging, and doScrap.
Now, we can have two of these three methods for example inherited from the parent class. That would be
doScrap and palletTagging. We can also have them overridden which means they inherit those methods but
they somehow alter them in some particular way. Then the child class can also have its own methods outside
of the parent class. So in this example, we're inheriting the doScrap method and the palletTagging method
from our parent class InventType. And then the child class has this updateTruckList method which is specific to
the child class in some way. So I've created a new class now that we're going to use to demonstrate the
concept of class inheritance. Now, in the last example, we walked through this dbfmVehicleEntry class. And
let's recap real quick what this class did. It created this dialog box with three dialog fields that took in the
user's input for a vehicle's make, model, and VIN number. It then inserted those values into the vehicle table
which we then saw on our VehicleListPage form. This dbfmTruck VehicleEntry class is going to extend the
functionality of the VehicleEntry class. And we do that by using this extends keyword. So we have class, our
class name, the keyword extends, and then the class name that this class extends. So what we're going to do is
borrow some functionality from that dbfmVehicleEntry class. This TruckEntry class takes in some more dialog
fields such as a FromNote, a FromNOD and a FromGVR. And these fields represent different values in the table
which are the note field in our vehicle table, the number of doors in our vehicle table, and the gross vehicle
weight in our vehicle table. And we're just calling them dialogFromNOD, dialogFromGVR as a shorthand way
to reference them. Now, again, this class is going to instantiate an instance of itself here saying new
dbfmVehicleEntry and then we call the truck VehicleEntry.run method. And it's going to walk through the same
process as the class we saw on the last example by creating our setupDialog and creating our getFromDialog
and getting the values from the user. Now, you'll notice here in our setupDialog method, we have this other
piece of code called super. And what the super does is it goes out to the parent class or the class being
extended, which is the VehicleEntry class, and it calls the code from the same method name. So we have a
method in our TruckEntry class here called setupDialog. That same exact method with the same exact name
exists right here in our parent class, the VehicleEntry class. And what the super does is goes ahead and
executes this code here in the parent class and then it executes the code we have here in our child class, the
TruckEntry class. So what it's doing is saving us from having to type out all those other dialog fields because
we're going to use the make, model, and VIN number fields from our VehicleEntry dialog on our TruckEntry
dialog as well, and there's no reason for us to specify all this code again to reinstantiate these dialog fields
because we've already coded them in this class. So we call the super to get those dialogs, and then when we
create our three new dialog fields that are specific to our TruckEntry form, which are the number of doors, the
gross vehicle weight, and this note field. And again, when we do the getFromDialog, we're creating three
strings. We're setting these strings equal to the value that's retrieved from those respective dialog fields. And
then, we're setting those to our vehicle table buffer variable so that that's now stored in the table, and then we
go back and call our insert method again. So the logic and the flow is the same as our entry class, our
VehicleEntry parent class, expect for we're calling the super to borrow some of those dialog fields here instead
of recoding them. Again, we call the super down here in this getFromDialog method. Now, you notice again in
our VehicleEntry parent class, we do have a method called getFromDialog. The getFromDialog method here is
retrieving the values for the make, model, and VIN number. So again, we're borrowing that code. We're
saying, hey, go out there and get the values for the make, model, and VIN number from our parent class as well
as the values here for our note, our number of doors and gross vehicle weight field. So let's go ahead and run
this class to see how it works with the concept of inheriting from our DB VehicleEntry parent class. OK. So I'm
going to use the shortcut key of CTRL ALT L to open up my Solution Explorer window. And I'll go ahead and
right click this TruckVehicleEntry class and set it as my startup object. I can then press CTRL F5 to go ahead
and build and run this class and see what the dialog window is going to look like. So I'll go ahead and do that.
All right. Our build has completed. We're getting a notification here from our class runner window. I'll open it
up and now we can see that we have this new quick entry dialog form. So we ran our TruckVehicleEntry class,
and that only had dialog fields for note, number of doors, and gross vehicle weight. However, using the
concept of class inheritance, we extended our VehicleEntry form which included these three dialogs for make,
model, and VIN number, and now, we have a new dialog window that encompasses all six of those fields
without having to rewrite a ton of code. And this is really the concept behind inheritance, to save us from
rewriting code and extending functionality of preexisting classes. So we can go ahead here and real quick, we'll
type in another model, a make, and we'll go ahead and just visualize how this is entered into our
VehicleListPage form. All right. So I'll make up some values and press OK. It's notifying me that that accepted
my input. So I can go back to my VehicleListPage here. And I'll press refresh. And now we can see that new
line of Toyota Prius with a gross vehicle weight of 5,000 is entered here on my VehicleListPage.

Lesson 6: Best Practices


In this lesson, we're going to review the best practices for classes. Some best practices to consider when using
classes include to have only one successful return point in the code which is typically the last statement with
the exception of switch cases or when checking for start conditions. We should keep our building blocks or
methods small and clear. A method should do a single well-defined job and, therefore, should be easy to
name. You should put braces around every block of statements, even if there is only one statement in that
block. You should also put comments in your code which tells others what the code is supposed to do and
what the parameters are used for. Do not assign values to or manipulate actual parameters that are supplied
by value. You should always be able to trust that the value of such parameter is the one initially supplied. You
should treat such parameters as constants as well. And finally, you should clean up your code, delete any
unused variables, methods, or classes, to keep everything precise and correct. An important best practice for
variable and method declaration is to declare them as locally as possible. We have three different types of
scopes that we can use for methods and variables. The first one is what's called public. We can declare
variables and methods for safe reuse by making them public. It's important to ensure that they are explicitly
declared and that there is no ambiguity as to the intention of the programmer. The public methods can be
accessed by other classes and methods. The private keyword or scope is used to declare variables and
methods as private. This means it keeps the context of the variables local or within the scope of that particular
method only. This prevents accidental misuse or unintentional variable reuse from outside classes or methods.
And finally, we have the keyword protected. This is a blend of the public and private scopes and protected
means to keep the variables public only for the subclasses that may extend or overlay. Yet it restricts access to
outside objects calls. This means a method with the protected keyword can be accessed by subclasses or child
classes that are used in an inheritance structure.

Module Review
Thanks for joining me in the classes module. We reviewed the structure of a class and the use of methods as
well as the different types of methods. We then demonstrated how a base class can use the concept of
inheritance, and then we created a child class to inherit from that base class. Finally, we reviewed the best
practices for using classes.

MODULE 13 KEY TAKE AWAY


o Classes

 Class Structure

 Class Construct

 Blue print

 Defines construction of building

 Instance method

 Work order

 Constructs the house

 Useable code

 Can use the house

 When done, it goes away


 Methods

 Class declaration

 Specifies name of class and necessary variable

 Can specify inheritance

 Instance methods

 Objective methods

 Embedded in each object created from class

 Must instantiate object before using method

 Static methods

 Class methods

 Belong to class and created by keyword static

 Do not need to instantiate object before using

 Used to work with data stored in tables

 Main methods

 Class method that’s executed directly from menu option

 Should only create instance of object

 Calls necessary member methods

 _args parameter allows data transfer to method

 Class Inheritance

 Objects created from Child have same methods and variable as Parent

 Objects created from Child may have methods and variable that do not exist in Parent

 Objected from Child may have methods from parent that are overridden or altered

 Best practices

 Only one successful return point in code


 Keep building blocks (methods) small and clear

 Put braces around every block of statements

o Even if just one statement

 Put comments in code

 Do not assign values to, or manipulate, actual parameters supplied by value

 Clean up code

o Delete unused variables, methods, classes

 Variable and Method Declaration

 Protected

 Private

 Public
MODULE 13: YOUR NOTES
Module 14: Database Manipulation
Welcome to Module 14 on database manipulation. In this module, we'll cover how to use X++ code
statements to manipulate data in the database. The objectives for this module are to review the data retrieval
process, to demonstrate best practices to use when updating data, to explain the transaction integrity system,
and finally, to review how to update and delete data.

Lesson 1: Fleet Management Scenario


In this lesson, we'll review our fleet management scenario for database manipulation. Data manipulation in
Dynamics AX empowers the developer with the tools to view, insert, update and delete data from the database.
For our fleet management system, all of these factors need to occur. For example, we might need to retrieve
data about our current customers. We might need to insert a new customer or we may have to update an
existing customer's details.

Lesson 2: Data Retrieval


In this lesson, we'll review the data retrieval process for viewing information from the database. Returning data
for view is a common feature. We can also use this for comparison. We will need to read records in from the
database. Single calls can be possible for uniquely indexed tables. And more effective searches iterate over
the whole table to ensure no item is missed. The select statement fetches or manipulates data from the
database, or both fetches and manipulates data from the database. All select statements use a table variable
to fetch records. This variable must be declared before a select statement can be executed. The select
statement only fetches one record or field at a time. To fetch additional records, you can use the next
statement. The next statement fetches the next record in the table. If you use next without a preceding select
command, an error will occur. You should not use next with the first only find option. If you need to traverse a
number of records, it's more appropriate to use the while select statement. The results of a select statement
are returned in a table buffer variable. If you use a field list in the select statement, only those fields are
available in the table variable. If you use an aggregate function on a particular field in a select statement such
as a sum or count, the results are returned in the field that you perform the sum or count over. You can only
count, average, or sum the integer in real fields. Using the following table, we can see that there are many
options available for using the select statement to retrieve data. We can specify different find options such as
find the first record only in a table or the first ten or the first 100 or even 1,000. We also have the option to
select an individual field from a table, a list of particular fields, or all fields which would be represented by the
asterisk so we can have something like select asterisk from cust table to retrieve all of the records in the cust
table. We then have aggregate functions that we can use such as sum, average, the min of, max of, and count.
And we would say something like select sum and then in parentheses, we would have the name of the field we
want to sum directly next to that. For example, we could have select sum and then the field amount in
parentheses from a particular table. We also have options to order our results or group our results. We can
have them be ordered ascending or descending and we can have them grouped by specific fields. So if we
want to select all records from the cust table ordered by customer account number, ascending, we can certainly
do that with the select statement. We also have the WhereClause and the JoinClause with specified conditions
on certain records that we want to return. For example, we can select all records from the cust table where a
customer lives in a certain state. We would say where the state field equals, and then we could put in
quotations the name of the state. The JoinClause allows to join to other tables. So we can construct a query
similar to how one would construct a query in SQL or we can select data from a table and join it to another
table. While select statements are used to handle data, they're the most widely used form of the select
statement in X++. While select loops over many records that meet a certain criteria, if we were to specify in a
WhereClause, and they can execute a statement on each record that they loop over. In a while select, the
select statement itself is executed only one time, immediately before the first iteration of the statements in the
loop. Also any expressions such as counter, less than one, that are added to the while select are only tested
one time. This differs from how the while statement behaves in other languages such as C++ and C#. When
you perform data manipulation by using the while select statement, you would typically do this in a transaction
to ensure data integrity. Let's consider the following sample while select statement. In this code snippet, we
have declared two tables that we'll be using in our code. The custTable and the dirPartyTable. These are the
aliases or the references that we're going to be referring to these tables as in the code below. We have a while
select statement and we are selecting the dirPartyTable and ordering it by the name column. Now, notice here
we didn't say while select name from dirPartyTable order by name. We could do that. However, we can also
simply say while select table name to select each record one by one from that table. And the results are going
to be ordered by the name field. It's important to keep in mind the order of these clauses. After our select
statement, we perform our orders and group bys, and then we perform our joins and where clauses. So in this
example, after we specify to begin selecting records from the dirPartyTable ordered by their name, we join the
custTable, and in the where statement, we specify this criteria to perform this join on. So we're joining the
custTable where the custTable.Party field is equal to our dirPartyTable.recID field. And these are related fields
that we can use as lookups between these two tables. So it's going to give us records from both tables and
loop over each one where there exists a record in each one for the party in recID field. And then once we're
inside this loop, for each record, we're going to display an info message that includes the dirParty name
followed by a comma and then followed by the customer account number. So let's go ahead and take a look
at how this will output in our development environment. I have pasted in our code snippet that we just
analyzed on our slide here. And again, we're declaring these two tables to use in our while select statement.
We're selecting every record from the dirPartyTable one by one, ordering them by name, and then we're
joining the custTable on this mutual field of custTable.Party and dirParty.recID. And then we're going to output
each line the dirPartyTable.Name field followed by a comma and then the customer account number. So I'm
going to go ahead and press CTRL F5 to run this class. Again, this is a runnable class that I've set as my startup
object in my project. Therefore, when I press CTRL F5, a build will be performed and the class will be ran. I'll
go ahead and do that now. And the build process will start. So our build process has completed. I'll open up
my class runner window in the AX client. And we can see here, we have 30 records that were outputted. If I
click the drop down here, you can scroll through them one by one, and we have our dirPartyTable.Name field
here followed by the comma and the associated customer account number with that customer. We can go
ahead and scroll through these one by one and we'll notice that the name field that we specified in our while
select to be ordered by the name is indeed ordered by the name. So here at the beginning, we have Birch
Company and we continue to scroll up through our records that were outputted in the loop and we can see
that name field is in alphabetical order.

Lesson 3: Reading Records


In this demonstration, we're going to look at how to view records within a particular table or set of tables. So
to do this, we use a select statement, a query to go specify which data we want and how we want to view it.
Now, here, I have this BulkVehicle class which is doing a bit of the same thing as our VehicleEntry class at the
beginning here. We're declaring two tables to use. That's our vehicle table and our vehicle maint table, which
is the vehicle maintenance table, and we have our main method that's creating a new instance of our class, and
we're calling it BulkVehicle. And then we call the run method on our class which is right below it here. And our
run method is going to perform these different types of data manipulation. In this example, we're using the
this.viewRecords, so we're calling it the viewRecords method, which is right here. And we'll go through this
method piece by piece. We also have the insertRecords, updateRecords, and deleteRecords methods, which
are further down in my code here. And we'll look at those later on. But currently, these are commented out.
You can see the text is green and we have these two forward slashes. This indicates that the compiler is going
to ignore these pieces of code. They're simply there for us to kind of flip around on. So I can go ahead and
put two slashes here to comment out the viewRecords method, remove these, and now I can run it with the
insertRecords method. OK. So let's go ahead and use our viewRecords method to retrieve some data from our
vehicle tables. Now, if we step down here to our viewRecords method, what we're doing is using a while select
statement on the vehicle maintenance table and we're joining in our vehicle table where the vehicle IDs in each
table are equal. So again, we're going through the vehicle maintenance table line by line. This is an iteration
over this table where this condition is met. And for each line where we have a matching vehicle ID in both
tables, we're going to output an info message that contains the vehicle ID followed by a comma and the
vehicle make. OK. So let's go ahead and run this and see how it outputs in our class runner. Now, before we
run a project, again, we have to make sure that the class we are running is set as our startup object. A quick
way to determine that is to look over here in the Solution Explorer in our project and we can see this
dbfmBulkVehicle class is in bold. That's an indication that it is the current startup object. And again, we can
right click any object and choose set and startup object. So for now, we're good to go. I'll go ahead and press
CTRL S to do a save and ensure there are no syntax or logic errors in my code. So we're looking good. I'll go
ahead and build and run this by using the CTRL F5 shortcut key. And then we should be able to verify the
output. OK. So our build has completed here. We'll go ahead and open our class runner window to verify the
Infolog message output. And we can see here on the right we have two records. I'll use my drop down arrow
and I have the vehicle ID of one with the make Toyota and the vehicle ID of five with the make Dodge. Now,
those are the only two records that exist in both those tables with the same vehicle ID. So our statement
worked. That's how we can go retrieve some data for output really quickly. If I go over here to my
VehicleListPage form, you can see that I kind of have this different demo data and I have a vehicle ID of one
here which is my Toyota and the vehicle ID of five is my Dodge. Now, if I click the vehicle maintenance button
up here from the top, that's going to launch my vehicle maintenance form that I have created. And we can see
in here that we'll only have two records. The one with the vehicle ID of one and the next maintenance record
with the vehicle ID of five. That's why we only received those two results in our output.

Lesson 4: Transaction Integrity Checking


In this lesson, we'll review the process for how AX performs transaction integrity checking. The transaction
integrity checking process is performed by the transaction tracking system which is commonly abbreviated as
TTS. It's important to ensure the integrity of all transactions within the system. When a transaction begins, we
need to ensure data consistency. It must finish completely with predictable results. If the transaction
terminates in the middle, the system should roll back to its state before the transaction began. Using the
transaction tracking system, we have three main keywords that we use to perform integrity checking. The first
one is ttsbegin. This indicates the beginning of a transaction. For example, if we're going to begin inserting
records or updating records in a table, we want to have the ttsbegin keyword before we begin that process.
The ttscommit keyword indicates the successful end of a transaction. This ensures the transaction finished and
performed as intended. If anything occurs between the ttsbegin and commit, for example, a particular record
in a while loop did not insert correctly, the ttscommit will never be reached and, therefore, nothing will ever be
inserted into the database. It rolls back to the state before the ttsbegin. And the third keyword associated with
the transaction tracking system is called ttsabort. It's used as an exception to abort and roll back the
transaction to the state before the ttsbegin. Nested ttsbegin and ttscommit statements are ignored in the
sense that the database lock is held until the very last ttscommit is reached. However, the system does keep
track of a TTS level. So each time a ttsbegin is called, the TTS level in the background increases by one. And
every time a ttscommit is reached, it decreases this TTS level by one.
Lesson 5: Data Insert
In this lesson, we'll review the process for inserting data. When performing data inserts, only the specified
columns of those rows selected by the query are inserted into the named table. That means you want to make
sure your query is selecting the fields that you're going to end up inserting into your table. Secondly, the
columns of the table being copied from and those of the table being copied to must be of type compatible.
For example, if we're inserting data into a field that stores some type of decimal number like fuel tank capacity,
we need to ensure that the table buffer variable is of the same data type, which would be the data type of real
in this case. Let's consider the following snippet of code. This is a sample insert statement. At the very
beginning, we are initializing a table buffer variable. We have a system table called
InventItemPriceToleranceGroup. And we're going to be using the InventItemPriceToleranceGroup here as our
table buffer variable. Then we're going to begin assigning data to certain fields in this table and then inserting
it into the actual table. Now, the first thing we do again is use our ttsbegin keyword. And then we can begin
the process of inserting data into this table. So we have a field here called itempricetolerancegroupid and
we're explicitly assigning this field a value of four percent. We then have a name field on this table and we're
explicitly assigning that to the value of TelevisionSeriesOne. And then we go ahead and call our insert
command. This calls the insert method on the InventItemPriceToleranceGroup table and inserts these two
records. Likewise, in the second paragraph, we're also assigning or inserting two new records. The
itempricetolerancegroupid is going to be assigned a value of six percent and the name is going to be assigned
TelevisionSeriesTwo. And then again, we call our insert method at our table and finally, our ttscommit
keyword. This ensures that there were no problems during these inserts, that the fields are type compatible
and everything goes smoothly. Then the ttscommit is called and the data is inserted into the table. And finally,
once our ttscommit is reached, we create an Infolog output here with the words Yahoo to indicate a success
transaction. So let's review this sample insert statement. This is the same snippet of code we just reviewed in
the slide. And here we have again a runnable class. We have our static main method and then some code here
that we want to test. And remember, we have to set this class as a startup object for our project so that when
we build and run it, it executes this class here. And you can do that by right clicking the class and choosing set
as startup object. So I've had this runnable class set as my startup object for all of the demonstrations so far.
Now, when he consider this code snippet, again, what we're doing is inserting data into this
InventItemPriceToleranceGroup table and we're inserting two records. So each time we call this insert method
here, it inserts a line or a row into the table. The first record is going to be this with the four percent
TelevisionSeriesOne set to the inventpricetolerancegroupid and name fields respectively and then we have six
percent in TelevisionSeriesTwo for the second record. Now, again, we are creating this table buffer variable
based on the InventItemPriceToleranceGroup table and we're assigning these variables, these fields different
values in our code. We have our ttsbegin and commit to ensure the integrity of the transaction, and then
finally we're going to display an Infolog message of Yahoo after the ttscommit has been reached to indicate
that the inserts were completed. We can also verify that on the InventItemPriceToleranceGroup form. So if I
navigate to the AX client here in my Internet Explorer browser, I'm open on the itempricetolerancegroup's
form. And we can see this form has no records. There's no data yet for this grid which is based on the
underlying table that we're about to insertRecords into. So we can go ahead and run our project and verify
that we see records inserted here on this form and we get that Yahoo output message. So let's go ahead and
do that. I have the code snippet here. I'll press CTRL S to save and verify there are no syntax issues. And
finally, I'll go ahead and do a build and run by pressing CTRL F5. So our build has completed here. I'm getting
a notification window from the class runner. So I'll open it up here. And we can see we have the info message
Yahoo displayed, which means our data was indeed inserted into the table. So let's go check the table now. Or
the form rather, which is based on the table. So I'll go ahead and refresh this form. And we should expect to
see those two records in the form now. And there they are. The four percent with TelevisionSeriesOne as the
name and six percent with TelevisionSeriesTwo as the name. In this demonstration, we're going to insert
records into our vehicle tables for our fleet management system. In the last demonstration, we called this
viewRecords method to retrieve and output some information, some records from our vehicle maintenance
and vehicle tables. And we did that using a while select statement and a join statement and then our Infolog
output. So now, what we're going to do is comment out this call to the viewRecords method by using two
forward slashes, then I'll uncomment, so I'll remove these forward slashes from the call to the insertRecords
method. And the insertRecords method is right here. And again, we're wrapping all of this insertion and data
assignment in our ttsbegin and commit. So in the first block of code here, we're simply assigning different
values for these variables in our table. For example, the vehicle ID, we're making a call to a method called
getLastVehicleID within this class and then we're incrementing that by one. So it's kind of a way to keep our
vehicle IDs incrementing and adding as we call this insert method. So let's go to the getLastVehicleID method
so we can see what's going on there. And the getLastVehicleID is here. It's a private method and it returns a
dbVehicleID value. You'll notice the other methods have this void keyword which means they do not return a
value. So the getLastVehicleID, what it's doing, it's saying return, and then in parentheses, we're creating a
query. We're saying select max of, and then the field name we want, dbVehicleID from the table we want,
which is dbVehicle, and then we specify the field name .vehicleID. So what we're doing is we're returning the
maximum value of the vehicle ID which would be the highest one. So I believe now we have a vehicle ID of six,
for example. So when we go here and assign a new value to the vehicle ID during this insert process, it's going
to increment the most recent or highest vehicle ID value by one so that we don't have any duplicate entries.
OK. Then we continue to assign different values for these variables. We're just assigning .75 for our fuel level
because that data type is a real -- it's a decimal data type. We need to make sure we're adhering to those. Our
year is a data field so we're using this make date function, which is the MK date and then parenthesis, and
we're specifying the month, day, and year. And that's a way to make a date field. Then we continue to just
type in some string tags for these make and models. We're going to use Toyota Corolla for an example. And
we're kind of just fabricating some numbers here and some inspection dates just to populate these fields. So
once we have all the fields we want, we call the insert method on our table buffer, FMVehicle, which is linked to
the actual dbVehicle table. And then again, we do some more insertions. We kind of repeat those same steps
with some different values, and then we call the insert again. And remember, each time we call the insert
method on a table, it's inserting a new line or a new record. And then we do one more block of code for a
third record and call our insert method once more followed by the ttscommit and then an Infolog to display
that the insertion of records has completed. So when I go ahead and run this code, we should expect to see
three new records in our VehicleListPage which is based on our vehicle table that we're updating. And we
should see a Toyota Corolla, a Ford Explorer, and a Dodge Charger. So let's go ahead and build and run this.
And again, we're calling the insertRecords method now so we're going to observe this process. I'll press CTRL
F5 to build and run. And once the build completes, we can verify the results. OK. Our build has completed.
We'll go ahead here and open up my class runner window. And we'll see we have our output insertRecords
complete. That means the code completed successfully. So let's see if we can verify those in our list page here
on our VehicleListPage form. I'll go ahead and refresh this. And we should expect to see those three records
inserted into the table. All right. And here we are. We have our incremented vehicle ID so that the highest
one before in this table was five. So you can see that getLastVehicleID method incrementing the value by one
assigned it to 6, 7, and 8 respectively. We have our make and model, Toyota Corolla, Ford Explorer, and Dodge
Charger. So those values all inserted properly into our table as we expected.
Lesson 6: Data Updates
In this lesson, we will review how to update data. The update command modifies existing data in a table with
the contents of a table buffer. The record is first retrieved from the database using a select statement. The
data is then modified by assigning the new values to the fields in the table buffer. The new values are then
committed to the database using the update method. Before records can be updated, use the select for
update keyword to exclusively set a record for update. This tells SQL that the record is to be updated and
allows the database to lock the record so that another user cannot modify it at the same time. Let's consider
the following code snippet that demonstrates a sample update statement. In this code, we have two tables.
The inventTable and the inventItemGroupItem table. We're performing a while select for update command
over the inventTable which means we're going through row by row and selecting certain rows for update. We
then perform an exist join between the inventItemGroupItem table and the inventTable where the ItemID fields
in both tables are equivalent. We're then using our and operator to specify an additional where condition
where our ItemGroupID in the inventItemGroupItem table is explicitly equal to TV and video. So we're
performing this update for the records in the inventTable that match these where conditions. So we're only
iterating over the rows where this join exists and where the ItemGroupID is equal to TV and video. Once we
enter the loop here within our brackets, this is the code we're executing onto each record that meets our
criteria. We're setting the itempricetolerancegroupid to seven percent in the inventTable and then we're saying
to call the update method, which will then update our inventTable. Finally, we display a this works message
from our Infolog and then we go ahead and use our ttscommit to ensure the integrity of the transaction and
that everything went smoothly during the update process. In this demonstration, we're going to look at how to
update records that already exist in our vehicle table. Again, we're here in our class called the BulkVehicle class
where we're updating and manipulating data. We have a run method that calls out to viewRecords method
and insertRecords method as well as an updateRecords and deleteRecords method. So we've already seen
examples of how the viewRecords method works with retrieving data, and then we just looked at the process
for inserting records in our insertRecords method. So now, we're going to comment out that call to the
insertRecord method and uncomment out this call to our updateRecords method. The updateRecords method
is down here in our code. And what this method is doing is calling a while select for update on the vehicle
table. And we're specifying a condition where the vehicle ID in that table is equal to six. Then we go in our
brackets here inside of our loop and we're saying set the model to Camry, and then we call the update method
on the vehicle table. So it's going to go through line by line the vehicle table, and any line that has a vehicle ID
of six, the model for that line will be changed to Camry. Now, we should only have one record with a vehicle ID
of six since that's our unique kind of numbering system for our fleet management system of vehicles. Now, I'll
go into my VehicleListPage real quick and we can verify that this record here with the vehicle ID of six is
currently a Toyota Corolla. So what our code is saying is to update this model, this Corolla field, and change it
to Camry now. OK. So we'll go ahead and run this and then we should observe that change. We should also
get an Infolog message that says updateRecords complete so that we know everything went through and our
ttscommit was performed successfully. So I'll go ahead and press CTRL S to save this. And then I'll use the
CTRL F5 shortcut key to build and run the project. We can now verify that our build has completed. And we'll
go ahead and check out our class runner window. And we can see the output update records complete so
everything should have gone through successfully. Now we'll switch over to our VehicleListPage form, and
we'll go ahead and do a refresh to see if that Corolla value will indeed change to Camry. And there it is. So our
vehicle ID of six. The Toyota Corolla is now a Toyota Camry. So that's a quick overview of how the update
method works. We can specify conditions on a certain field and then update another field. We can also
update multiple fields at once, just like when we insertRecords, we can insert into multiple fields with one insert
call.
Lesson 7: Data Deletion
In this lesson, we will cover data deletion using X++ code. The last piece of data manipulation we're going to
discuss is the delete method. The delete method in a table can quickly delete one record, dozens, or even
millions of records. It's very important to test this procedure in a non-production database with a small
amount of data to ensure the results are what you expect. Using the delete method on a table will delete the
current record from the database. However, if we use a WhereClause, we can specify multiple rows to be
deleted that meet our conditions. Records are then removed one at a time from the specified table. The
delete method can also be overridden. For example, we can add extra validation before records are deleted
from the table. Let's take a look at a sample delete statement. This code snippet is similar to what we saw in
our sample update statement. We have these two tables, the inventTable and the inventItemGroupItem table.
And we're performing a while select for update on the inventTable. We're then performing an exist join
between the invent item group item table and the inventTable. And that exist join is being performed where
the ItemIDs are equivalent. And then we're using our and operator to specify an additional piece of criteria,
and that is where the ItemGroupID field is TV and video within the inventItemGroupItem table. So what we're
doing is we're going through line by line the inventTable and we're saying where this criteria is met, where
there is a record in the inventTable that relates to a record in the invent item group item table, that has an
ItemGroupID of TV and video, we're going to delete all the instances of those records one by one using this
while loop. So we're calling the delete method on the inventTable for all of these records that meet our criteria
in our where statements. And finally, we're calling the Infolog to display a message that says this works as a
confirmation and ultimately using our ttscommit to ensure that everything went well. In this demonstration,
we're going to delete some records from our vehicle table. And again, we have this run method and it's
making calls to different methods that either update, insert, delete, or allow us to view and retrieve records.
Now, we've seen examples of these first three here. So now we're going to focus on calling the deleteRecords
method. So I've commented out the other three so that we only execute the deleteRecords method. And we'll
scroll down here and take a look at the code. Now, on the deleteRecords method, we're calling a while select
statement for update on the vehicle table. And then we're specifying a condition where the vehicle ID is equal
to zero. Now, again, typically our vehicle ID field is going to be a unique kind of numbering system so this
would only delete one record. However, let's go check out our VehicleListPage and see what data we have in
that data right now. Now, you can see I have all this kind of demo data I had keyed in and they all have a
vehicle ID of zero. So I'm going to specify that in my where clause so I can kind of clean up this table a bit with
all these anomalies and I'll just leave my vehicle IDs of 1, 4, 5, 6, 7 and 8. So let's go ahead and try to execute
that code. So what we're going to do now is call the delete method on our vehicle table for all the records that
have a vehicle ID of zero. And finally, we're going to display this delete records complete in our Infolog output
to confirm that the code has run successfully. So again, I'm going to press CTRL S to save and ensure there are
no errors in the code. And then I'll kick off a build and run the project by pressing CTRL F5. So our build has
completed. I'll go ahead and open up my class runner window in AX. And we'll verify our info message has
been outputted that says deleteRecords complete. So I'll flip over to my VehicleListPage and I'll go ahead and
refresh this and we should expect to see all these records with a vehicle ID of zero disappear. And there we
are. So all those records are gone and now my form and my table here are looking nice and clean.

Module Review
Thanks for joining me in the database manipulation module. In this module, we covered how to retrieve and
review records. We explained the transaction tracking system and discussed the best practices to use when
updating data. Then, we reviewed how to insert, update, and delete data using X++ code.
MODULE 14 KEY TAKE AWAY
o Database Manipulation

 Database Retrieval

 Returning data for view is a common feature

 You will need to read records from the database

 Single calls can be possible for unique index tables

 More effective searches iterate a whole table to ensure no item is missed

 Select statement

 Using the select statement

 Using a table variable with a select statement

 Fetching additional records with the “next” and “while select” statements

 Results of select statement are returned in a table buffer variable

 While Select Statement

 Loops over many records and can execute statements on each record

 In a while select, the statement is executed only one time, immediately before the
first iteration of statements in loop

 When performing data manipulation using the whole select statement, you
would typically do this in a transaction to ensure data integrity

 Transaction Integrity Checking

 Ttsbegin

 Indicates beginning of transaction

 Ttscommit

 Indicates successful end of transaction.

 Ensures transaction is performed as intended upon completion

 Ttsabort
 Used as exception to abort and roll back transaction to state before ttsbegin

 Data Insert

 Only specified columns of rows selected by query are inserted into named table

 Table columns being copied from and those of the table being copied to must by type
compatible

 Data Updates

 Update command modifies existing data in table with contents of table buffer

 New values are then committed to database using update() method

 Before records can be updated, use “select forUpdate” to exclusively set record for
update

 Data Deletion

 Deletes current record from database

 Use this method, specify which rows are to be deleted by using a where clause.

 Records are then removed one at a time from specified table

 Delete method can be overridden, for example, to add extra validation before records
are deleted.
MODULE 14: YOUR NOTES
Module 15: Exception Handling
Welcome to Module 15 on exception handling. The objectives in this module are to define the different
exception types, to discuss the key commands to use in X++ code, to review the code statements for exception
handling and to create a try/catch statement.

Lesson 1: Fleet Management Scenario


In this lesson, we will review the fleet management scenario for exception handling. For the fleet management
scenario, we're going to explore error handling. In a previous example, we built the VehicleEntry class, which
took user input values from dialog fields and quickly inserted that data into our vehicle table. Now, we have
created a copy of this class and added a try/catch statement for validation. When the user keys in a value, we
would like to verify that they have the correct vehicle identification number or VIN. VINs are 17 digits in length
and our company using 18 digits with a special check digit to ensure that we have the correct vehicle type.

Lesson 2: Exception Types


During this lesson, we will discuss the different exception types in AX. There are many different exception
types, and the type differs depending on what caused the error. A majority of exception types are determined
by the kernel and are not normally thrown by application code. All exception types, however, can be caught,
and it is the developer's responsibility to decide which exceptions need to be handled. The exception type is
identified using the system-based enumeration called exception. Because it is a system enum, it cannot be
modified and users cannot add new exception types. The first exception type we're going to discuss is called
info. And this displays informational exceptions. For example, a record has been updated. The warning
exception type indicates the user has performed an illegal but non-fatal operation. Deadlock informs the user
that the system encountered a deadlock situation in the database. The error exception type indicates a fatal
error has occurred and the transaction has been stopped. Internal displays Microsoft AX internal development
errors. The break indicates that the user has pressed the break button or shortcut key. A dderror exception
indicates that an error occurred in the DDKernel class. The numeric exception type indicates that some error
has occurred during the conversion of converting a string to integer, string to integer 64, or string to numeric
functions. The CLRError indicates that an error has occurred during the use of a CLR functionality. The
CodeAccessSecurity exception type indicates that an error has occurred during the use of
CodeAccessPermission.demand. The UpdateConflict exception type indicates that an error has occurred in a
transaction using optimistic concurrency control and that the transaction will be retried. The
UpdateConflictNotRecovered exception type indicates that an error has occurred in a transaction using
optimistic concurrency control and that the code will not be retried.

Lesson 3: Key Commands


Let's review some of the key commands in X++ that we will use with exception handling. We're going to
discuss four main key commands that are used in code to use with exception handling. The first one is called a
try statement. The try command signifies the start of a block of code that you want to control with the X++
exception handling system. Any exceptions that are thrown in that block of code can be caught and handled
accordingly. The block of code inside the try statement must be contained between brackets. Catch
statements come after the block of code and define what code is executed when each exception is thrown.
You do not have to define a catch statement for every possible exception. However, each try statement must
have at least one catch statement. A retry command tells the system to go back to the try statement and
attempt to execute the code again. Any data that was loaded before the try command will remain as it was but
any data retrieved or modified after the try statement will be refreshed. When a deadlock exception is thrown,
all locks on tables that this process holds are released which may allow the other process or processes that are
also deadlocked to continue. By calling it a retry, the process can attempt to update the record again and may
now be able to complete. It's a best practice that a retry uses a counter so that the number of retries can be
controlled and a user does not become stuck in a loop. Lastly, we have the finally keyword. This is used to
follow the try and catch keywords. The semantics are identical to its use in C#. The statements provided in the
finally clause are executed irrespective of whether the try block threw any exceptions or not.

Lesson 4: Code Statements


In this lesson, we will review some sample code statements that use exception handling. Let's consider this
following code sample for exception handling. The current code snippet spans three different slides so we'll
walk through each slide and discuss each piece of the code. Now, here in the first slide, we have a class called
custCreateCustomer. Then we have a static main method. Inside this main method, we are instantiating a new
instance of our class calling it custCreateCustomer using our new keyword. And then we're calling the run
method on our custCreateCustomer class. The run method is on the next slide here. And within our run
method, we're creating a dialog object with the heading that says create new customer and it's going to have
two dialog fields. The user can input values for the customer account number and the customer group number
and then we're going to set those values or insert those values into our customer table. However, first, we're
going to make sure -- we're going to perform this validation using a try/catch statement. So we have an if
statement that says if the dialog object is running, we go ahead and call our try statement. The try statement
encapsulates everything within the opening and closing brackets so the opening bracket is here. The closing
bracket is in another segment of code on the next slide. So at the beginning of this try statement, we're simply
assigning the value inputted in the dialog box by the user to our custTable AccountNum field and then the
same thing for the CustGroup field in the custTable. Now, in the following slide, here's the ending closing
bracket for our try statement. Therefore, all of this is included. And we have another if statement here that's
calling the ValidateWrite method on the custTable. Now, the ValidateWrite method ensures that the data
being inserted is able to be written correctly, that it passes the validation tests. For example, it has the required
mandatory fields for that table. Now, we have an exclamation point preceding this method call which means if
not, if the ValidateWrite method does not pass, then we're going to throw this error. It's an exception of type
error and output the message please enter all required fields. If, however, this ValidateWrite method passes,
we skip this if logic and we go directly to our else statement. And from there, we simply insert the records
because they're already validated. Now, below our try statement, after the closing bracket, we have a catch
statement. And the catch statement is looking out for an exception of type error. And when this throw error
comes through, if the ValidateWrite method does not pass, it will get caught in our catch statement. Therefore,
we will see an error message outputted that says an error occurred, please try again. In this demonstration,
we're going to look at a try/catch statement to handle errors in our VehicleEntry form. So what I have created
here is a new class called dbfmVehicleEntry with exceptions. And it's identical to our VehicleEntry class that we
saw in the previous example that takes in these three different dialog fields for vehicle make, model, and VIN,
and then ultimately attempts to insert them into the vehicle table. The only difference in this class is that we've
changed the heading for demonstration purposes to quick VehicleEntry form with VIN validation and we've
added our actual validation here in the getFromDialog method. In our getFromDialog method, we have our try
statement here. And it's encompassed in between everything in between these two set of brackets, so all this
code is in our try statement, and then we have our catch statement immediately afterwards. So in our try block
of code, we have our three variables for make, model, and VIN that we are assigning the value from the input
on the respective dialog fields. And we begin our validation with an if statement. And what this if statement
says is if the string length for the VIN variable or field is less than 17 characters, we will throw an exception of
type error with the message please enter a valid VIN number. We have the else statement which handles the
situation where this if condition is not true. So if we have a valid VIN number that is 17 characters or greater,
this statement here will not execute. It will go immediately to the else block where we will assign those
variables to our table buffer for the make, model, and VIN, and ultimately call the insert method to insert the
data into our vehicle table, since the criteria was met for validation on the VIN length. Now, again, if the VIN
string length is less than 17 characters, it will throw this error message, and then our catch statement here is
looking for an exception of type error. Once it finds that exception of type error from this throw message, it
will also execute this block of code here which is an error statement that says an error occurred, please try
again. So if we attempt to insert a VIN field with less than 17 characters, we should observe this error message
here in addition to this error message here. Now, we'll notice this exception. We mentioned this is a system
enum. So just to demonstrate how this works, if I use the double colon right after the exception, IntelliSense
will populate a list of the different exception types I can choose from for this system enumeration. Now, we're
using error for this example, so I'll just leave that. You'll also notice we have these breakpoints inserted in this
class here. So in this gray pane on the left, we have the red dots and we can add these simply by clicking a line
and then clicking again to remove. Additionally we can use a shortcut key of F9 to insert breakpoints. Now,
when I run this code, we're going to use two different scenarios. In the first scenario, we'll enter a VIN number
with less than 17 characters to observe the errors and how our try/catch statement handles those. And then
we'll attempt to insert a VIN with a valid string length of 17 or 18 characters at which point the data should be
inserted into our vehicle table. Now, to begin the debugger, I launch our code from our first breakpoint here
which is the call to the getFromDialog. We press F5. In previous examples, we've been running all of our
classes or forms using the CTRL F5 shortcut key which runs the project without debugging. And you'll notice if
we click the debug menu, we can start debugging and it has the F5 as the shortcut key, or we can start without
debugging. Additionally, we have the shortcut keys of F10 and 11 to step through our code while we're in the
process of debugging. So I'll go ahead and press F5 to start the debugging process and we can step through
the breakpoints and observe how this code is executing. OK. So now, we are in debugging mode and we can
see our lines of code that have breakpoints have kind of been highlighted here in this maroon color. So what's
happened is the code has executed all of this code so far, and it comes to my first breakpoint and now stops.
And we can observe that our class runner has executed this code, and now we have our quick VehicleEntry
form with VIN validation opened. And we're stuck here on this call to the getFromDialog method. So I'll go
ahead and enter some data here. And then we'll proceed stepping through the code and see how the
validation will occur. For my VIN number, I'm going to type in a VIN with a character length of 16. So this
should throw an error. So we'll press OK. And it's going to begin processing so I can go ahead and use the
F10 key to step through my code. And we can see now it's highlighted in yellow with a little yellow arrow here
in the left pane to show me which line of code I'm on. So I've pressed F10. Now I come to my if statement
where we are performing this comparison. I'll press F10 again. It's going to continue going through the lines
of code one by one each time I press the F10 key. And we can see it hit this throw error line. It then came
directly to the catch statement. We did not enter this else criteria since our string length was less than 17
characters. So I'll keep pressing F10 until I reach the end of my code. OK. So now we've started back through
again at the beginning. I'll press the little stop button here. We can also use the shift F5 shortcut key to stop
the debugger. Now go back to my class runner, and here we have our error messages. There's a drop down to
indicate that there are two messages. The first, please enter a valid VIN number from our throw error
statement, and the second, an error occurred, please try again, from our catch statement. So that data was not
inserted into the table. Now we're going to walk through an example of where our VIN number has a valid
string length of 17 characters or greater and, therefore, will pass our try/catch validation. So again, we're here
in the same class and I've already pressed F5 to enter our debug mode, and we can begin stepping through
this step by step. So since I'm in the debug mode, all of my code from the beginning of the class is executed
up until this very first breakpoint on the call to the getFromDialog method. So that means our class runner has
opened, and we can begin entering values into this dialog. So I'm going to try again with a Ford Mustang.
And this time the VIN number is going to have 18 characters. So I'll pipe this up to eight again. So that's 18
digits. And we'll press OK. And it's going to begin executing the code. So again, we notice this yellow
highlighted line on the call. And we'll press F10 to step through and we'll follow along. Now we're in our if
statement. OK. So we can see it skipped over this throw error code because it met the criteria for the else
statement which is 17 characters or greater. Now, if I keep pressing F10, it will go through these three lines of
code to assign our variables. And ultimately, this line here where it's going to insert the data into our table. It
skips over the catch statement. It does not execute that code since there was no exception of error thrown.
OK. Now, that completes the walk-through of those blocks of code. I can go to my class runner now and verify
that this has been inserted into our table. So now we'll go ahead and stop debugging so I'll go back to Visual
Studio. And stop the debugging process. We'll go back to our class runner and we can see that the class has
completed executing. There are no error messages to display. So let's go to our VehicleListPage form here
and we'll refresh it to see if that record for the Ford Mustang was indeed inserted. And here we have it. So we
didn't set a vehicle like D on that form, but we did insert the Ford Mustang into the underlying table, and it has
a VIN number associated with it that is valid.

Module Review
Thanks for joining me in the exception handling module. In this module, we covered the different exception
types. We discussed the key commands in X++ to use with exception handling. We then reviewed some code
samples and demonstrated the functionality of a try/catch statement.

MODULE 15 KEY TAKE AWAY


o Exception Handling

 Exception Types

 Info

 Displays informational exceptions

 Warning

 Indicates user has performed and illegal, yet nonfatal operation

 Deadlock

 Informs user that the system encountered a deadlock situation the database

 Error

 Indicates fatal error has occurred and transaction has stopped

 Numeric
 Indicates an error has occurred during the use of str2int, str2int64 or str2num
functions

 Dderror

 Indicates an error accured in the DDkernal class

 Break

 Indicates user has pressed Break.

 Internal

 Displays AX internal development errors

 CLRError

 Indicates error has occurred during use of CLR functionality

 CodeAccessSecurity

 Indicates error has occurred during use of CodeAccessPermision.demand

 UpdateConflict

 Indicates error has occurred in transaction in a transaction using Optimistic


Concurrency Control, and that the transaction will be retired

 UpdateConflictNotRecovered

 Indicates error has occurred in a transaction using Optimistic Concurrency


control, and that the code will not be retired

 Key Commands

 Try

 Signifies start of block of code

 Catch

 Come after block of code

 Define what code is executed when exception is thrown

 Retry
 Tells system to go back to Try statement and reattempt

 Finally

 Follows try and catch keywords


MODULE 15: YOUR NOTES
Module 16: Security Basics
Welcome to the security basics module. In this module, we will look at the architecture for security and review
some security elements and properties. The objectives for the security module are to review the security
architecture, to explain role-based security, to describe security elements in the development environment, to
modify and create security in the development environment, and to describe the extensible data security
framework and how to use XDS policies.

Lesson 1: Security Architecture Overview


Let's begin by reviewing security architecture. Let's see how authentication for the user interface works. First,
the user signs in to AAD, which is Azure Active Directory. Next, Azure Active Directory redirects to the
Dynamics AX client or the web application. And finally, the Dynamics AX start page is displayed. OData
services, JSON-based custom service, and the REST metadata service support standard OAuth 2.0
authentication. Certain applications can consume AX web services. For example, PowerBI can consume data
from the OData service. Microsoft Azure Active Directory uses two types of authentication. The first is the
native client application. This is the flow that uses a user name and password for authentication. Next, is
what's known as the confidential client or the web application, and this is an application that can keep a client
password confidential to the world. The basic flow in this diagram is that the first step is outlining a user
authenticating and consenting for access. The client would then receive an authorization token. This is in step
two. In step three, the client requests access to a resource with an authorization code. In step four, the client
would then receive an access token. In step five, the client requested data with this access token. And finally,
in step six, the client would then receive the data that it requested. The following diagram represents the
security model in AX. The security model is hierarchical, and each element in the hierarchy represents a
different level of detail. Permissions represent access to individual securable objects like menu items and
tables. Privileges are composed of permissions. And they represent access to tasks such as cancelling
payments and processing deposits. Duties are composed of privileges and represent part of a business process
such as maintaining bank transactions. Both duties and privileges can be assigned to roles to grant access to in
AX. AX security is role-based. This means many security roles and duties are provided to help base security
definitions. Using role-based security, users are assigned to roles based on their responsibilities in the
organization. Instead of identifying and granting access to application elements, the administrator assigns
duties which users in the role perform. Because rules can be set up for automatic role assignment, the
administrator does not have to be involved each time a user's responsibilities change. After security roles and
rules are set up, role assignments are updated based on changes in business data. A single set of roles apply
across all companies and organizations. The administrator does not have to create and maintain a separate
user group for each company. Even though roles themselves are not specific to a company or organization, the
administrator can still specify a company or organization context for a particular user in a role. Let's take a
closer look at how this structure and elements in security work with each other. Authentication for users can
occur in Active Directory or Active Directory Federated Services, for example. The authorization process for
users includes security roles. Each user must have at least one security role but they may have multiple roles.
And each role we mentioned can have privileges and duties assigned to them. The privileges contain
permissions for application elements to perform a specific task on that element. Data security is implemented
through data security policies, record level security, and the table permissions framework. In the following
screen shot, we're seeing an example of the system administration users and user's page where we can see the
details of a particular user. Security roles that are assign to a user determine the duties that the user can
perform and the parts of the user interface that the user can view. Administrators can apply data security
policies to limit the data that the users in a role have access to. An example of this would be a user in a role
may have access to data only from a single organization. The administrator can also specify the level of access
that the users in a role have to current, past, and future records. By managing access through security roles,
administrators save time because they do not have to manage access separately for each user. Security roles
are defined one time for all organizations. In addition, users can automatically be assigned to roles based on
business data. An example of this could be the administrator set up a role that associates a human resource
position with a security role. Anytime that users are assigned to that position, those users are automatically
added to the appropriate security roles. Users can also be automatically added to or removed from security
roles based on the Active Directory groups that they belong to. Security roles can be organized into a
hierarchy. A role hierarchy enables roles to be defined as a combination of other roles. For example, the sales
manager role can be defined as a combination of the manager role and the salesperson role. In the security
model for AX, duties and privileges are used to grant access to the program. For example, the sales manager
role can be assigned to maintain revenue policies and review sales orders duties. By default, sample security
roles are provided. All functionality in AX is associated with at least one of the sample security roles. The
administrator can assign users to the sample security roles, modify the sample security roles to fit the needs of
the business, or create new security roles. By default, the sample roles are not arranged in a hierarchy. The
following screen shot shows an example of the system administration security and security configuration page.
And from here, we have different tabs where roles, duties, and privileges can be assigned and configured. We
talked a little bit about security roles and we mentioned they can be assigned duties and privileges. We also
have process cycles. A process cycle cannot be assigned to a role. However, a process cycle is a business
process that is coordinating a set of activities in which one or more participants consume, produce, or use
economic resources to achieve an organizational goal. To help the administrator locate the duties that must be
assigned to roles, duties are organized by the business processes that they are a part of. In the context of a
security model, business processes are referred to as process cycles. An example of this is in the accounting
process cycle, you may find the maintain ledgers and maintain bank transactions duties process cycles used for
organization only. The process cycles themselves cannot be assigned to roles. We also discussed duties a little
bit and we can see here in the screen shot how duties can be added to a specific role. Duties correspond to
parts of a business process. And the administrator assigns them to security roles. A duty can also be assigned
to more than one role. In the security model for AX, duties contain privileges. An example of a duty is the
maintain bank transaction duty, and it contains the generate deposit slips and cancel payment privileges within
that duty. You can assign related duties to separate roles. These duties are said to be segregated. By
segregating duties, you can better comply with the regulatory requirements such as those from Sarbanes-Oxley
or the United States Food and Drug Administration. In addition, the segregation of duties helps reduce the risk
of fraud and helps you detect errors or irregularities. Default duties are provided. The administrator can
modify the privileges that are associated with the duty or create new duties. We then have privileges. In the
security for AX, a privilege specifies the level of access that is required to perform a job, solve a problem, or
complete an assignment. Privileges can be assigned directly to roles. However, for easier maintenance, it's
recommend that you assign only duties to roles. A privilege contains permissions to individual application
objects such as user interface elements and tables. An example of a privilege is the cancelled payments
privilege which contains the permission to the menu items, fields, and tables that are required to cancel
payments. By default, privileges are provided for all features in Dynamics AX. The administrator can modify
the permissions that are associated with the privilege or create new privileges. We also have the concept of
permissions. And in the security model for AX, a permission grants access to logical units of data and
functionality like tables, fields, and forms as well as server side methods. Only developers can create or modify
permissions. For more information about how to work with permissions, refer to the Dynamics AX developer
documentation. We will discuss the data security elements in more detail later in this module. The screen shot
on the right shows the security configuration form where administrators can create and edit roles and view the
duties and privileges and so on that are related to one another. The extensible data security framework in AX
enables developers and administrators to secure data and share tables such that users have access to only the
part of the table that is allowed by the enforced policy. This feature can be used in conjunction with role-based
security to provide more comprehensive security than was possible in the past. The extensible data security
commonly abbreviated as XDS is an evolution of record level security that was available in previous versions.
XDS security policies, when deployed, are enforced regardless of whether data is being accessed through the
AX web interface, SQL Server reporting services reports, or other services. An XDS policy starts with a query to
define the filters or limits that should be placed on the primary table or tables. The data, that is. Then you will
create a security policy which is linked to the query and primary table that you want to restrict data for. Next,
you will define the context for the rule which could be based on a string for a role or group of roles. This could
require additional programming to function properly. Lastly, you can define the list of constrained tables which
are related tables that store data from the primary table that you're attempting to restrict a subset of data for.
Several common design principles are used when creating the base 80-plus roles. These design principles
include the following. Roles represent the common access rights that are required for the job positions within
an organization. Roles account for the organization size, culture, and industry focus. Users are assigned to one
or more roles according to their job. There are also different role types. For example, a functional role could
be a warehouse worker. An organizational role might be an employee. And an application role could be a
system user. We also have role segregation categories. Functional roles are designed to accommodate
segregation of duties. Different categories of roles exist that each focus on their own type of responsibilities.
For example, validation. Clerks focus on recording transactions. Or verification. Verifiers validate the
correctness of recorded transactions. Another segregation category is authorization. Supervisors authorize the
processing of transactions. And then we could have management. Managers review transactions periodically
and apply changes to the process as needed.

Lesson 2: Create a Role


Roles can be created by a developer in Visual Studio or by a system administrator in the AX client. In this
course, we're going to focus on the process for a developer to create a new role from Visual Studio. In this
demonstration, we'll look at creating a security role to add to our development basics fleet management
scenario project. And to do that, we'll right click our project and we'll choose add and new item. In the left
pane under AX artifacts, there's a security group. And this contains the different elements related to security.
So we'll choose security role and we'll give this new role a name such as DBDataEntryClerk and choose add. A
new folder will be created in our project for this new element type of security role and you'll notice in the
designer, we have this role opened. And we have four different sub-nodes here within our role. We can add
privileges, duties, permissions, as well as sub-roles within this role. In this example, we're going to add a
privilege as well as a duty. To add those, we simply click the node we wish to add, and we right click and
choose new. So I'm going to right click privilege and choose new privilege. And in the properties pane, there's
a property called name. And from here, we can use a drop down to select from the list of populated privileges
in the system. We can also go ahead and key it in. Since there can be a few in that list, I'll go ahead and just
type one in. This privilege is going to be called sysDataAreaMaintain. And that is a privilege that exists in the
system. And I'll repeat a similar process to add a duty. This time I'll right click the duties node and choose new
duty. And for the name property, I'll specify the name of my duty. This one I'm going to call data management
maintain. And I'll press enter. And now we have created this new role. We've added a privilege and a duty
and we specified which system, duty, and privilege we want to be associated with those. So I'll go ahead and
save this object. And now we're ready to begin using our role.
Lesson 3: Create a Duty
Just like roles, a duty can be created both in the UI by a system administrator and in the development
environment by a developer. In this course, we'll walk through the process for creating a duty in the
development environment. In the previous demonstration, we created the DBDataEntryClerk role in our
development basics fleet management scenario project. We then added a privilege to this role and a duty to
this role. In this demonstration, we're going to create a new duty and we'll assign a privilege to that duty and
then ultimately we will add our newly created duty to our DBDataEntryClerk role right here. So to add a new
duty, we right click our project, we'll go to add and new item, and from the security artifacts group, we'll
choose security duty. We'll go ahead and call this dbVehicleDuty. And we'll choose add. And again, it's going
to create this new folder for the duties and it will open up in our element designer. And we can see the
dbVehicleDuty only has one node and that is the privileges node. So we can go ahead and right click this and
choose new privilege. And then in the name property, I'll specify value. It's InventADJInventonHand. And this
relates to a system privilege that is to approve purchase orders. So once I have assigned this privilege to my
dbVehicleDuty, I will go ahead and save. Then I'll flip over to my DBDataEntryClerk role, and I will add my new
dbVehicleDuty to this role. So again, so again, on my DB data clerk entry role, I'll right click the duties node
and choose new duty. And this time in the name dialog box, I'm going to specify the name of the duty we just
created which is dbVehicleDuty. And I'll press enter. And we'll see it appear here. Now, by adding this duty,
we also add the privilege to approve purchase orders that is associated with this duty.

Lesson 4: Security Properties on Key Elements


Certain elements in the system have properties that affect or control how security will work. Let's take a closer
look at some of those. There are three main security permission properties for buttons that we're going to
discuss. The first one is called needed access level. This can have values like no access, edit, create, delete, or
view. If we set the needed access level property to no access, then every user will have full access to this
button. The next property is called needed permission. And this specifies the minimum permission level
needed to allow access to that button. This property represents a hierarchy where read is the weakest
permission in the hierarchy and delete is the strongest. Above the read hierarchy level, we have the update
permission which is one level higher than read. Therefore, the update permission also includes the read
permission below it in the hierarchy. The create permission is higher than the update and read permissions.
Therefore the update and read permissions are also included in the create permission. The third property for
buttons is called needs records. This specifies whether the button will be enabled when no records are present.
The available values for this property are yes or no. Let's review some of the security permission properties for
table fields. The first one we're going to discuss is the allow edit property. And this specifies whether a user is
allowed to modify data in an existing record in a form when a table field exists on a form. The allow edit on
create property determines whether the users are allowed to enter data in the field when a new record is
created in a form. The mandatory table field property indicates whether a user must add data to a field in a
form. If it's set to yes, that indicates that the default or initialization value for each data type is not acceptable
and another value must be supplied. The minimum read access property can be set to yes or no. If it's set to
know, then no access will be granted to that field. If the minimum read access is set to yes, then view access
will be granted to that field. Otherwise, view access will be granted if it's part of the natural key auto
identification field group. Or if it's a title field or system field. Let's review some of the security permissions
properties on form fields. The first one we're going to discuss is the allow edit property. And this specifies
whether you can modify data in the control. When this property is set on a container control, modifications are
either disabled or enabled for all controls within that container. The mandatory property determines whether
users must enter data into the control. If the mandatory property is set to yes, a red wavy line will be displayed
on empty fields. A warning sign will also be displayed if the user tries to navigate away from the field without
completing it. The needed permissions property specifies the minimum permission level needed to allow
access to the form control. The values for the needed permission property represent a hierarchy, read being
the weakest permission and delete being the strongest. Read is included by the update permission which is
one level higher in the hierarchy. Then we have the create permission which is above both the read and
update permissions and, therefore, includes the read and update permissions with it. Now let's review some of
the security permissions properties for menu items. And the first one we're going to discuss is the correct
permissions property. This specifies whether correct permission will be available to select when privileges are
assigned to this menu item. The options can be set to auto or no. Auto means the permission will be available
to select as a privilege on this menu item. No means the permission will not be available to select as a
privilege on the menu item. The default value is auto. Create permissions is a similar property, except it
specifies whether the create permission will be available to select when privileges are assigned to the menu
item. The options again are auto and no where the default value is auto, and that means the permission will be
available to select as a privilege on this menu item. No means the permission will not be available to select as
a privilege on the menu item. The delete permissions again specifies whether the delete permission will be
available to select when privileges are assigned to the menu item. The options also are auto and no with a
default value being auto and auto says the permission will be available to select as a privilege on this menu
item. And no means the permission will not be available to select as a privilege on this menu item. We then
have the linked permission object property. This specifies the name of another object or element, for example
a form or report, whose permissions are to be applied to this menu item. This is typically used with action
menu items. We then have the linked permission object child, and this specifies if there is some object, child
object associated with the main linked permission object whose permissions should be applied to this menu
item. We then have the linked permission type. This specifies the type of object pointed to by the linked
permission object property. For example, the linked permission type could be form or it could be report. We
then have the read permissions property. And this specifies whether the read permission will be available to
select when privileges are assigned to this menu item. The values again are auto and no, where the default
value is auto and the permission for auto means it will be available to select as a privilege on this menu item.
And no means it will not be available to select as a privilege. And finally, we have the update permissions. This
specifies whether the update permission will be available to select when privileges are assigned to this menu
item. Again, we have two possible values with auto and no. When the default value is auto, auto means the
permission will be available to select as a privilege on this menu item, and no means the permission will not be
available to select on this menu item.

Module Review
Thanks for joining me in the security basics module. We took a look at the architecture for authentication and
the security model in AX. We also looked at how to create new roles and duties from the Application Explorer
in Visual Studio. And lastly, we looked at key security related properties for buttons, table fields, form fields,
and menu items in AX.

MODULE 16 KEY TAKE AWAY


o Security Basics

 Security Architecture

 Authentication for the user interface


 Sign in via AAD

 AAD redirects to AX

 AX start page displayed

 Authentication for services

 Apps consume AX web services

 AX web services (OAuth)

 Apps granted delegated access

 Security Authorization and Access Control

 Security roles

o All users must be assigned a security role

o Determines duties user can perform and what they can view on interface

 Process cycles

o Coordinated set of activities in which participants consume, produce, and


use economic resources to achieve organizational goals.

 Duties

o Correspond to parts of business process

o Admin assigns duties to security roles

o Can be assigned to more than one role

 Privileges

o Specifies level of access required to perform a job, solve a problem or


complete an assignment

o Can be assigned directly to rules

o Recommended only assign duties to roles

o Contains permissions to individual app objects

 Permissions
o Grants access to logical units of data and functionality

o Only developers can create/modify permissions

 Extensible Data Security Framework

 Query

 Security policy

 Context

 Constrained tables

 Role Design Principles

 Roles represent common access rights required for job positions

 Roles account for organization size, culture, industry focus

 Users are assigned to roles according to their job

 Role types

o Functional role

o Organizational role

o Application role

 Role segregation categories

 Security Properties on Key Elements

 Button Properties

 Needed access level

 Needed permission

 Needs record

 Table Fields

 Allow edit

 Allow edit on create


 Mandatory

 Minimum read access

 Forms Fields

 Allow edit

 Needed permission

 Mandatory

 Menu items

 Correct permissions

o Specifies whether correct permission will be available to select when


privileges are assigned to the menu item

 Create permissions

o Specifies whether create permission will be available to select when


privileges are assigned

 Delete permissions

o Specifies whether delete permission will be available

 Linked permission object

o Specifies type of object to by the LinkedPermissionObject property

 Linked permission object child

 Linked permission type

o Specifies name of another object who’s permissions are applied to this


menu item

 Read permissions

o Specifies whether read permission will be available to select when


privileges are assigned to this menu item

 Update permissions
o Specifies whether update permission will be able to select when privileges
are assigned to the menu item
MODULE 16: YOUR NOTES
Module 17: Introduction to Advanced Topics
In this module, we're going to introduce at a high level some of the more advanced features and capabilities of
AX. The objectives for this module are to review the business intelligence features, to review the reporting
framework, to explain the services and integrations, and to define and create data entities.

Lesson 1: Business Intelligence


In this lesson, we'll walk through the BI features that are available in AX. Some of the new BI features in AX
include in-memory aggregate models. These aggregate models have replaced SSAS cubes. There's also the
concept of aggregate data entities. These are read-only entities that are used for reporting purposes. When
you're building charts or other client controls, you can add aggregate data entities to a form as a data source.
You can then consume these data entities programatically. The aggregate programming model enables a
developer to consume this data programatically using X++ or C# code. Method expressions also enable a
developer to build rich expressions using aggregate data. Method expressions are written in X++ and KPIs can
be modeled using them which eliminates the need for complex MDX queries. An aggregate measurement is a
model that contains a collection of measures together with their corresponding dimensions. So measures are
aggregate numbers like total sales or number of orders, and dimensions are slicers to slice those measures by,
such as product or vendor. So a total sales number is really kind of useless unless we can slice it by total sales
by customer or by product. So these aggregate measurements help you analyze data in a new way. These are
the evolution of cubes. Aggregate dimensions are another concept which are shared across an AX
implementation. Aggregate measurements associate themselves with relevant aggregate dimensions. For
example, total sales can be associated with a customer, a product, or a sales region. However, total sales can't
be associated with a vendor. Aggregate dimensions and measurements are modeled using AX in Visual Studio
tools. In AX, users can use a rich client form to modify a KPI definition. Users can also define new KPIs by
using the aggregate data that is contained in the aggregate measurements. After a KPI is defined, users can
customize it at runtime. There are three main types of BI in terms of AX. The first is contextual BI. This refers
to providing required insights as part of the user experience such that the user has relevant insights to not only
achieve the task at hand but to be highly productive during the course of the day. Embedded BI refers to
analytic content being embedded within AX within the user experience on a form for example. Contextual BI
and embedded BI teams are closely related. Contextual BI implies the added notion that the context of analytic
content resolves around the data or the task at hand. And finally, self-service BI refers to enabling the user to
tweak existing reports or create their own new analytic content such dashboards and KPIs. Microsoft PowerBI
is a collection of tools and services that enable interactive visualizations and dashboards. You can access
PowerBI visualizations from PowerBI.com with a free account. Dynamics AX integrates with PowerBI by being a
first-class data source of PowerBI authoring tools such as Microsoft Excel. After reports are authored, they can
be published at PowerBI.com for collaboration and mobile access. Although dashboards and reports can be
used on PowerBI.com, they can also be pinned to the Dynamics AX client to provide interactive visuals that are
related to business processes. Prebuilt AX content packs from Microsoft and their partners offer ready-made
analytical dashboards and reports for industry verticals. Users can deploy these content packs directly from
PowerBI.com. Tiles and charts created in PowerBI can be pinned in the AX client as well. As users view reports
and visuals in PowerBI.com, they can drill back into the Dynamics AX client to take action on trends and
exceptions and data. Users see only data that is relevant to them and that they have access to.
Lesson 2: Reporting Services
Now let's take a look at SQL Server reporting services in AX. In Dynamics AX, reporting services are hosted in
the Microsoft Azure compute service. If you're developing in a one-box environment, this service is also run
locally in the Azure compute emulator. In a one-box environment, developers can easily modify, create, and
preview reports from end-to-end, all within Visual Studio 2013. A separate process is not required to add
reports to the application object tree on the application server. Changes to reports that are packaged together
with other solution updates are uploaded and deployed to the cloud only after development is completed in
the local environment. The enhanced report viewing experience for end users in Dynamics AX is the same as
the report preview in Microsoft Visual Studio. By pressing CTRL F5 in the development environment, you can
build and preview the report in an Internet Explorer window. The report will appear exactly as it would in the
client. You do not have to set up or administer a local report server for development because the reporting
services run in the Azure compute emulator together with the application server. After reports have been
deployed to the local reporting services, they can be accessed from the client. The process of developing a
report is easy in Dynamics AX because you can create and validate a reporting solution entirely within Visual
Studio. Let's take a look at the high-level steps for the report development process. We would first create a
reporting project in Visual Studio. We would then edit the report in Visual Studio. Next, we would add the
report to a menu item and set the menu item as the startup object for our project. We would then use the AOT
to deploy the report to the report server. Finally, we would press CTRL F5 to verify the report design in the
Dynamics AX client. When the whole solution is completed, you can deploy it to the cloud in one package.
Some of the advantages of SSRS reports include the built-in back-office document management capabilities.
This includes things such as e-mail support or scheduled executions via batch. We also have parameterized
views and drill-through navigations so we can click on particular items in the report and be taken to other AX
pages and reports. We also have precision documents to comply with local regulatory business practices. The
financial reporting area is where users can access 22 default financial reports. These reports were previously
accessed using an integrated reporting tool called management reporter. This feature allows users to run
financial statements such as a balance sheet or an income statement directly from the AX web client in the
browser. The 22 default reports that come with AX can be edited and new ones can also be created. The
financial reporting menu can be found in the following places in Dynamics AX. We can navigate to the general
ledger, inquiries and reports and then choose financial reports. The financial reporting functions are available
to users who have the appropriate privileges and duties assigned to them in order to run the reports. Users
with the security administrator role assigned to them can view, edit, and manage the financial reports. In order
to create and generate financial reports for a legal entity, the following needs to be set up for that particular
entity. They must have a fiscal calendar set up, a ledger set up, the chart of accounts need to be set up, and
they have to have a currency established.

Lesson 3: Services and Integration


During this lesson, we'll explore some of the services and integrations available in Dynamics AX. All of service
groups under the AOT service group node are automatically deployed. All services that must be deployed
must be part of a service group. This diagram lists all of the service endpoints that are available in Dynamics
AX. Data entities can be used for importing and exporting data. They can also be consumed via an OData
protocol and then used on reports or integrated into PowerBI, and X++ classes can be consumed via the SOAP
and REST services which use HTTP/XML, HTTP and the JSON protocol respectively. Consuming external web
services is also supported by creating a class library project in Visual Studio. Open data protocol or OData is a
standard protocol for creating and consuming data. OData applies web technologies such as HTTP and
JavaScript object notation, which is JSON, to provide access to information from various programs. It supports
a uniform URL convention for features like filtering and sorting data. More information on OData URL syntax
can be found at OData.org. OData entities in Dynamics AX are based on the concept of an updatable view.
When the is public property for an updatable view is set to true, that view is exposed as a top-level OData
entity. Dynamics AX introduces a public OData service endpoint that enable access to Dynamics AX data in a
consistent way across a broad range of clients. Dynamics AX also introduces the Version 4 of OData which
supports consumption and PowerBI as a refreshable data source as well. Dynamics AX integrates with
Microsoft Office. One of the featured integrations is the Excel data connector app. This app interacts with
Excel workbooks in Dynamics AX OData services that are created for publicly exposed entities. The Excel data
connector app enables Excel to become a seamless part of the Dynamics AX user experience. The data
connector app is built by using the apps for Office framework. It runs in a task pane that contains all app-
related actions and information. Office applications are web applications that run inside an embedded Internet
Explorer browser window. The Excel data connector app supports data refresh and publishing back to AX. The
export to Excel feature is a static export of grid data directly to an Excel spreadsheet. This is useful for quick
analysis of data. Another integrated feature of AX is the workflow editor. A workflow represents a business
process. It defines how a document flows or moves through the system by showing who must complete a task,
make a decision, or prove a document. For example, the following figure shows a workflow for expense
reports. The workflow editor is a program that you click one time to download. The editor communicates with
Dynamics AX by using services. Therefore, Dynamics AX can carry a rich graphical workflow design experience.
Workflow development wizards have imported into Microsoft Visual Studio. Three components of workflows
include consistent processes. You can define how specific documents such as purchase requisitions and
expense reports are processed. Process visibility allows you to track the status history and performance metrics
of workflow instances. This helps you determine whether changes should be made to the workflow to improve
efficiency. A centralized work list allows users to view a central list of work that displays the workflow tasks and
approvals that are assigned to them.

Lesson 4: Data Entities


In this lesson, we will discuss the use and application of data entities in AX. A data entity is an abstraction from
the physical implementation of database tables. For example, in normalized tables, a lot of the data for each
customer might be stored in a customer table and then the rest might be spread across a small set of other
related tables such as an address table, for example. In this case, the data entity for the customer concept
appears as one denormalized view in which each row contains all of the data for the customer table and its
related tables. Data entities also provide a single stack to capture business logic. They provide a primary
mechanism to insert and extract data sets. And this can be used to replace the diverging concepts of the DIXF
entities or the data import/export framework entities. The following diagram illustrates the concept of a
denormalized view. The current normalized model contains a customer table with some information about a
customer such as their account number. It then relates out to another table called a party table where we have
a party number and name. And that table reaches out further to an electronic address and an address table
that contain more information about the customer such as their city, their phone number, e-mail address, and
all this information about our customer entity is split up into these four different tables. This can complicate
processes such as data importing and exporting. The concept of the denormalized views depicted on the right.
We have a customer entity and a single denormalized customer entity view. And all of these fields that are in
different tables here are now stored into one larger table. Let's take a look at the different data entity
categories. The first one is the parameter category. And this has functional or behavioral parameters. This is
required to set up a deployment or a module for a specific build or customer. It can include data that is
specific to an industry or business and the data can also apply to a broader set of customers. We then have
the reference data entity category. This includes simple reference data of small quantity that is required to
operate a business process. Examples of this include units, dimensions, and tax codes. Next, we have the
master data entity category. And this is the data assets of the business. Generally, these are nouns such as
people, places, and concepts. Complex reference data of large quantity is included in this category. Some
examples are customers, vendors, and projects. The next data entity category is called document. This is
worksheet data that is converted into transactions later. Documents that have complex structures such as
several line items for each header record are a good example of a document data entity. Other examples are
sales orders, purchase orders, open balances, and journals. The last data entity category we're going to discuss
is the transaction category. This is the operational transaction data of the business such as posted transactions.
Typically, these items are excluded during a full data set copy. An example would be pending invoices. Let's
review some use cases for data entities. The first one is synchronous services. Data entities enable public
application programming interfaces known as APIs on entities to be exposed which enables synchronous
services. Synchronous services are used for Office integration as well as third-party mobile apps. Data entities
also support asynchronous integration through a data management pipeline. This enables asynchronous and
high-performing data insertion and extraction scenarios such as interactive file-based import/export or
recurring integrations. Data migration is streamlined by using data entities in denormalized views. Data
entities also enable BI features by creating aggregate data entities which can then be used for reports, data
sources on forms, as well as be accessed programmatically. Data entities can be added to a project in Visual
Studio just like any element. When you initially add it, a data entity wizard will guide you through the process
of adding and configuring it. At completion, it will create a data entity along with an optional staging table.
You can also right click a table in the table designer in Visual Studio and choose add-ins, create data entity.

Module Review
Thank you for joining me in the introduction to advanced topics module. We reviewed some of the exciting BI
features like KPI modeling and integration with PowerBI. We then discussed reporting capabilities, financial
reporting, as well as services and other integrations. Finally, we reviewed types of data entities and their
different uses.

MODULE 17 KEY TAKE AWAY


o Introduction to Advanced Topics

 Business Intelligence

 BI Features

 In-memory aggregate models

 Aggregate data entities

 Aggregate programming model

 Aggregate measurements and dimensions

 New KPI modeling

 Types of BI
 Contextual BI

 Embedded BI

 Self-Service BI

 Power BI Integration

 Data refresh and mobile access

 Dynamics data

o Feeds

o Export

o Pre-built

 Insights in Excel

o Discover

o Analyze

o Visualize

 Collaborate in PowerBI.com

o Share

o Find

o Mobile

 Embed in Dynamics

o Pin

o Launch

o Act

 Reporting Services

 Overview

 Services hosted in Microsoft Azure Compute service


 Simplified development

 Simplified administration

 Enhanced report viewing

 Development Process

 Create reporting project in Visual Studio

 Edit report in Visual Studio

 Add report to menu item

 Set menu item as start up object

 Deploy report to server

 Use CTRL + F5 to verify the report

 Advantages of SSRS Reports

 Built-in back-office document management capabilities

 Precision documents to comply with local regulatory business practices

 Parameterized views and drill-through navigations to other AX pages and other


reports

 Financial Reporting

 22 default financial reports

 Users can edit or create new reports

 Requires proper privileges and duties

 Services and Integrations

 Overview

 All service groups under AOTService group are automatically deployed

 All services that must be deployed must be part of a service group

 Consuming external web services is supported


 Open Data Protocol (Odata) V4

 Provides a simple and uniform way to share data in a discoverable fashion

o Uniform URL conventions

 Enables broad integration across products

 Supports consumption in PowerBI.com as a refreshable data source

 Office Integration

 Excel Data Connector app

 Export to Excel

 Workflows

 Consistent processes

 Process visibility

 Centralized work list

 Data Entities

 About

 Replace diverging concepts of DIXF entities

 Provide primary mechanism to extract/insert data sets

 Provides single stack to capture business logic

 De-normalized view of database tables

 De-normalized View

 Customer

o Account number

o Customer group

o Bank account

 Party
o Party number

o Name

 Address

o Postal address

o City

 Electronic Address

o Phone

o Email Address

o Fax

 Customer Entity

o Account number

o Customer group

o Bank account

o Party number

o Name

o Primary postal address

o Primary email

o Primary fax

 Data Entity Categories

 Parameter

 Reference

 Master

 Document

 Transaction
 Data Entity Use Cases

 Synchronous services

 Asynchronous integration

 Data migration

 Business intelligence

 Creating Data Entities

 Add new data entity to a project and follow the wizard

 Build entity directly from a table


MODULE 17: YOUR NOTES

You might also like