Sunteți pe pagina 1din 162

COURSE: 80304

DEVELOPMENT II IN
MICROSOFT DYNAMICS AX 2012

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Last Revision: August 2011


This courseware is provided as-is. Information and views expressed in this courseware, including URL and other
Internet Web site references, may change without notice.
Unless otherwise noted, the examples depicted herein are provided for illustration only and are fictitious. No real
association or connection is intended or should be inferred.
This courseware does not provide you with any legal rights to any intellectual property in any Microsoft product.
Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under
copyright, no part of this courseware may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means or for any purpose, without the express written permission of Microsoft
Corporation.
Copyright 2011 Microsoft Corporation. All rights reserved.
Microsoft, Microsoft Dynamics, Microsoft PowerPoint, Microsoft SQL Server data management software
and Microsoft Dynamics AX are trademarks of the Microsoft group of companies. All other trademarks are
property of their respective owners.
This course content is designed for Microsoft Dynamics AX 2012.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Table of Contents
Introduction

0-1

Welcome ............................................................................................................ 0-1


Microsoft Dynamics Courseware Contents ........................................................ 0-2
Documentation Conventions .............................................................................. 0-3
Student Objectives ............................................................................................. 0-4

Chapter 1: Introduction to X++

1-1

Objectives ........................................................................................................... 1-1


Introduction ......................................................................................................... 1-1
Characteristics of X++ ........................................................................................ 1-2
Scenario ............................................................................................................. 1-2
Development Tools ............................................................................................ 1-2
Reverse Engineering ........................................................................................ 1-17
Best Practices .................................................................................................. 1-19
Lab 1.1 - Print to the Screen ............................................................................ 1-22
Lab 1.2 - Debug the Job ................................................................................... 1-23
Lab 1.3 - Create a Data Model ......................................................................... 1-24
Lab 1.4 - Create an XML Developer Document ............................................... 1-25
Summary .......................................................................................................... 1-26
Test Your Knowledge ....................................................................................... 1-27
Quick Interaction: Lessons Learned ................................................................. 1-28
Solutions ........................................................................................................... 1-29

Chapter 2: X++ Control Statements

2-1

Objectives ........................................................................................................... 2-1


Introduction ......................................................................................................... 2-1
Introduction to Variables ..................................................................................... 2-2
Operators ........................................................................................................... 2-6
Conditional Statements .................................................................................... 2-10
Loops ................................................................................................................ 2-16
Lab 2.1 - Create a Times Table Using a While Loop........................................ 2-20
Lab 2.2 - Create a Times Table Using a Do...while Loop ................................. 2-21
Lab 2.3 - Create a Times Table Using a for Statement .................................... 2-22
Built-in Functions .............................................................................................. 2-23
Communication Tools ....................................................................................... 2-24
Lab 2.4 - Create a YesNo Box ......................................................................... 2-31
Lab 2.5 - Create an Infolog Tree ...................................................................... 2-32
Lab 2.6 - Create a Dialog Box .......................................................................... 2-33
Lab 2.7 - Use X++ Control Statements ............................................................ 2-34
Summary .......................................................................................................... 2-36
Test Your Knowledge ....................................................................................... 2-37
Quick Interaction: Lessons Learned ................................................................. 2-39
Solutions ........................................................................................................... 2-40

Chapter 3: Objects and Classes

3-1

Objectives ........................................................................................................... 3-1


Introduction ......................................................................................................... 3-1
Classes ............................................................................................................... 3-2
Lab 3.1 - Create a New Class ............................................................................ 3-4

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Development II in Microsoft Dynamics AX


Method Access Control ...................................................................................... 3-5
Lab 3.2 - Allow Access to Methods .................................................................... 3-6
Inheritance .......................................................................................................... 3-7
Objects ............................................................................................................... 3-8
Lab 3.3 - Instantiating a Class .......................................................................... 3-10
Scoping and Parameters in X++....................................................................... 3-11
Lab 3.4 - Use Method Parameters ................................................................... 3-13
Referencing Object Methods ............................................................................ 3-14
Lab 3.5 - Create a Run Method ........................................................................ 3-15
Method Types ................................................................................................... 3-16
Tables as Classes ............................................................................................ 3-18
Eventing ........................................................................................................... 3-18
Lab 3.6 - Create a Calculator Class ................................................................. 3-22
Summary .......................................................................................................... 3-24
Test Your Knowledge ....................................................................................... 3-25
Quick Interaction: Lessons Learned ................................................................. 3-26
Solutions ........................................................................................................... 3-27

Chapter 4: Accessing the Database

4-1

Objectives ........................................................................................................... 4-1


Introduction ......................................................................................................... 4-1
Retrieving Data ................................................................................................... 4-2
Lab 4.1 - Retrieving Data ................................................................................. 4-10
Data Manipulation ............................................................................................ 4-11
Lab 4.2 - Update ............................................................................................... 4-15
Queries ............................................................................................................. 4-17
Lab 4.3 - Create a Query Using X++ ................................................................ 4-21
Summary .......................................................................................................... 4-22
Test Your Knowledge ....................................................................................... 4-23
Quick Interaction: Lessons Learned ................................................................. 4-24
Solutions ........................................................................................................... 4-25

Chapter 5: Exception Handling

5-1

Objectives ........................................................................................................... 5-1


Introduction ......................................................................................................... 5-1
Exceptions .......................................................................................................... 5-2
Try and Catch Statements .................................................................................. 5-3
Throwing Exceptions .......................................................................................... 5-4
Optimistic Concurrency Exceptions .................................................................... 5-6
Lab 5.1 - Handle an Exception ........................................................................... 5-8
Summary .......................................................................................................... 5-10
Quick Interaction: Lessons Learned ................................................................. 5-13
Solutions ........................................................................................................... 5-14

Chapter 6: Security for Developers

6-1

Objectives ........................................................................................................... 6-1


Introduction ......................................................................................................... 6-1
Permissions ........................................................................................................ 6-2
Security Policies ................................................................................................. 6-3
Code Access Security ........................................................................................ 6-6

ii

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Table of Contents
Display Method Authorization ............................................................................. 6-8
Summary ............................................................................................................ 6-9
Quick Interaction: Lessons Learned ................................................................. 6-11
Solutions ........................................................................................................... 6-12

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

iii

Development II in Microsoft Dynamics AX

iv

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Introduction

INTRODUCTION
Welcome
We know training is a vital component of retaining the value of your Microsoft
Dynamics AX 2012. investment. Our quality training from industry experts
keeps you up-to-date on your solution and helps you develop the skills necessary
for fully maximizing the value of your solution. Whether you choose Online
Training, Classroom Training, or Training Materials; there is a type of training to
meet everyone's needs. Choose the training type that best suits you so you can
stay ahead of the competition.

Online Training
Online Training delivers convenient, in-depth training to you in the comfort of
your own home or office. Online training provides immediate access to training
24 hours-a-day. It is perfect for the customer who does not have the time or
budget to travel. Our newest online training option, eCourses, combine the
efficiency of online training with the in-depth product coverage of classroom
training, with at least two weeks to complete each course.

Classroom Training
Classroom Training provides serious, in-depth learning through hands-on
interaction. From demonstrations to presentations to classroom activities, you
receive hands-on experience with instruction from our certified staff of experts.
Regularly scheduled throughout North America, you can be sure you will find a
class convenient for you.

Training Materials
Training Materials enable you to learn at your own pace, on your own time with
information-packed training manuals. Our wide variety of training manuals
feature an abundance of tips, tricks, and insights you can refer to again and again:

Microsoft Dynamics Courseware


The Microsoft Dynamics Courseware consists of detailed training manuals,
designed from a training perspective. These manuals include advanced topics as
well as training objectives, exercises, interactions and quizzes.
Look for a complete list of manuals available for purchase on the Microsoft
Dynamics website: www.microsoft.com/Dynamics.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

0-1

Development II in Microsoft Dynamics AX 2012

Microsoft Dynamics Courseware Contents


Test Your Skills
Within the Microsoft Dynamics Training Materials you find a variety of different
exercises. These exercises are offered in three levels to accommodate the variety
of knowledge and expertise of each student. We suggest you try the level three
exercises first, if you need help completing the task look to the information in the
level two exercises. If you need further assistance each step of the task is outlined
in the level one exercise.

Challenge Yourself!
Level 3 exercises are the most challenging. These exercises are designed for the
experienced student who requires little instruction to complete the required task.

Need a Little Help?


Level 2 exercises are designed to challenge students, while providing some
assistance. These exercises do not provide step by step instructions, however, do
provide you with helpful hints and more information to complete the exercise.

Step by Step
Level 1 exercises are geared towards new users who require detailed instructions
and explanations to complete the exercise. Level 1 exercises guide you through
the task, step by step, including navigation.

Quick Interaction: Lessons Learned


At the end of each chapter within the Microsoft Dynamics Training Material, you
find a Quick Interaction: Lessons Learned page. This interaction is designed to
provide the student with a moment to reflect on the material they have learned.
By outlining three key points from the chapter, the student is maximizing
knowledge retention, and providing themselves with an excellent resource for
reviewing key points after class.

0-2

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Introduction

Documentation Conventions
The following conventions and icons are used throughout this documentation to
help you quickly and effectively navigate through the information.
CAUTION: Cautions are found throughout the training manual and are preceded by
the word CAUTION in bold. Cautions are used to remind you of a specific result of a
specific action which may be undesirable.
HINT: Hints are found throughout the training manual and are preceded by the word
HINT in bold. Hints are used to suggest time-saving features or alternative methods for
accomplishing a specific task.
NOTE: Notes are found throughout the training manual and are preceded by the word
NOTE in bold. Notes are used to provide information which, while not critical, may be
valuable to an end user.
BEYOND THE BASICS: Advanced information found throughout the training manual
is preceded by the words BEYOND THE BASICS in bold. Beyond the Basics provides
additional detail, outside of standard functionality, that may help you to more optimally
use the application.
EXAMPLE: Examples are found throughout the training manual and are preceded by
the word EXAMPLE in bold. Examples bring to light business scenarios that may better
explain how an application can be used to address a business problem.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

0-3

Development II in Microsoft Dynamics AX 2012

Student Objectives
What do you hope to learn by participating in this course?
List three main objectives below.
1.

2.

3.

0-4

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++

CHAPTER 1: INTRODUCTION TO X++


Objectives
The objectives are:

Identify key features of developing with X++.

Describe the basic foundation of object-oriented programming.

Use the development tools available within Microsoft Dynamics


AX.

Create object and data models from existing application elements by


using the Reverse Engineering tool.

Use best practices to instill good programming habits.

Introduction
X++ is the primary programming language used in the MorphX Development
environment. When you develop with X++, refer to Microsoft Dynamics AX
Developer Help, available from the Help menu for detailed information. The
following are important features of X++:

X++ resembles other popular languages such as C# and Java. Due to


this resemblance, programmers already familiar with these languages
will be able to transition into the MorphX development environment
quickly.

Because X++ includes many integrated SQL commands, Microsoft


Dynamics AX can build complex accounting and business
management systems.

X++ is an object-oriented language and provides a clean and


efficient object-based development platform.

Programmers who use X++ can access existing Microsoft Dynamics


AX system classes that provide functionality ranging from basic I/O,
XML, to changing controls in the graphical user interface at run
time. These system classes can be extended to provide new behavior.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-1

Development II in Microsoft Dynamics AX 2012

Characteristics of X++
The following are characteristics of X++:

Reliable: X++ provides extensive compile-time checking, followed


by a second level of run-time checking. Language features guide
programmers toward reliable programming habits. The memory
management model is simple; objects are created by using a "new"
operator and there is automatic garbage collection. There are no
explicit programmer-defined pointer data types or arithmetic. This
model eliminates entire classes of programming errors.

Interpreted and Dynamic: Benefit from faster development cycles prototyping, experimentation, and rapid development, versus the
traditional compile, link, and test cycles.

Interoperable: Components in Microsoft Dynamics AX are


seamlessly available to any application supporting .NET, and
conversely X++ is able to consume external managed code and COM
objects.

Scenario
Systems developers in a large development environment have joined a team that
is customizing a Microsoft Dynamics AX application. This is the team's first
project in X++ so they need to learn what development tools are available to
them within Microsoft Dynamics AX.

Development Tools
All elements that comprise the Microsoft Dynamics AX application (classes,
forms, tables, and more) are organized in the Application Object Tree (AOT).
This is a central, organized index to all application elements, displayed in a
graphical tree view.
Microsoft Dynamics AX customizations are developed by modifying one or
more elements from the AOT. These elements are usually assembled in a project,
or, in other words, a container for elements that implement an application in
Microsoft Dynamics AX. Projects help manage development efforts by
organizing units of functionality.
As developers create new projects or modify existing projects, they use a series
of development tools. These tools include the following:

1-2

X++ Editor

X++ Compiler

X++ Debugger

Visual Studio

Visual Studio Debugger

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


Other tools exist to aid developers while writing code and for managing
modifications they make to elements in the AOT.
All these tools, apart from Visual Studio, are accessible from the Development
Workspace. This is a unique version of the regular workspace, designed
specifically for developers to work in. To launch a development workspace press
Ctrl+Shift+W from the regular workspace. Alternatively, a command line
parameter (-development) can be added to the Microsoft Dynamics AX client
shortcut, to automatically launch in the development workspace. Development
cannot be done in the regular workspace, so a development workspace must be
opened before doing any development.
The development workspace tools are described in the following sections.

The X++ Editor


Double-clicking many of the nodes in the AOT opens them in the X++ editor.
The X++ editor can also be started by selecting View Code in the right-click
context menu.
The X++ editor window consists of two panes:

The left pane contains a list of current methods or jobs

The right pane displays the X++ code

FIGURE 1.1 CODE EDITOR WINDOW

There are several toolbar buttons in the heading of the X++ editor window.
Many of these functions can be started using keyboard shortcuts. Moving the
pointer over these buttons reveals the button's function. These buttons are
described in the following table:

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-3

Development II in Microsoft Dynamics AX 2012


Button

Keystroke

Description

New

Ctrl + N

Creates a new method or job.

Save

Ctrl + S

Saves the changes to the active


method.

Undo

Ctrl + Z

Undo the last edit.

Redo

Ctrl + Y

Redo the last undone edit.

Go

F5

Executes the class, form, or project.

Toggle Breakpoint

F9

Turns breakpoints on and off.

Enable/Disable
Breakpoints

Ctrl + F9

Enables or disables a breakpoint.

Remove all
breakpoints

Ctrl + Shift
+ F9

Deletes all breakpoints from the


method.

Compile

F7

Checks the code for errors, compiles


the code, and saves it.

Lookup label/text

Ctrl + Alt +
Space

Helps you find a label.

Script

Alt + R

Helps you choose between a selection


of scripts.

Add to Version
Control
Check In

Alt + I

Checks in the current element.

Check Out

Alt + O

Checks out the current element.

Undo Check Out

Alt + U

Reverts all edits since the last check


out.

History

Opens the Version Control History


form.

Get Latest

Get latest version of the element from


Version Control history.

Help

1-4

Adds the current element to Version


Control and checks the element out.

F1

Accesses the X++ editor window help.

Toggle line
numbers

Turns the line numbers on and off.

Toggle change
tracking margin

Turns the change tracking margin on


and off.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


To make reading easier, the X++ editor color-codes different kinds of code as
follows:
Color

Code type

Blue

Reserved words

Green

Comments

Dark Red

Strings

Bright Red

Numbers

Purple

Labels

Black

Everything else

Jobs
A job is a stand-alone block of code in Microsoft Dynamics AX that can be run
from the X++ editor. Jobs are used primarily for testing code during development
and running batch processes within Microsoft Dynamics AX that affect large
amounts of data.
This course uses jobs as a mechanism to write code and run it directly from the
X++ editor. Most code for applications is written in classes, methods, tables, and
forms. However, jobs are useful for testing blocks of code before inserting them
into methods or classes.
The following is default code when you create a new job in the AOT:
static void Job1(Args _args)
{
}

NOTE: Unlike classes and other elements in the AOT, jobs can only be renamed
in the Code Editor. Most other AOT elements can have their name changed in the
Property window, or directly on the AOT node.
Create a new job by right-clicking the Job node on the AOT, and selecting New
Job. The X++ editor opens, displaying the new job. The job can be renamed in
the text editor or in the AOT. In the example above, the job is called Job1 and
can be renamed by change Job1 to the required namein the text editor.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-5

Development II in Microsoft Dynamics AX 2012


Compiler
When code that is written in X++ is ready to be executed, use the compiler. The
compiler is a translation program that converts X++ into a language that can be
interpreted.
Code can be compiled by clicking the Compile button in the X++ editor toolbar
or by pressing F7. It can also be compiled by right-clicking the node in the AOT
and selecting Compile.
In this course you will also learn about inheritance. Classes that inherit from, or
extend, other classes can be compiled by right-clicking the main class, then
selecting Add-Ins > Compile forward. This means any changes that are made to
the main class are propagated down to the sub-classes correctly.
Use the Compiler Output window to view information to help improve and
correct errors in the code. The Output window will update its contents every
time a compilation is performed.

FIGURE 1.2 COMPILER OUTPUT WINDOW

There are four different compile result types:


Result type

Description

Error

These are compile errors, and must be resolved before


code can be run.

Warning

These are compile warnings, and should be resolved,


but will not prevent the code from being run.

Best Practice

These are found when an element contains code or


properties that deviate from the list of Microsoft
Dynamics AX Developers Best Practices. Best Practice
deviations are only found by the compiler when the
Diagnostic level is set to Level 4. The Diagnostic level
is a parameter accessible from the Setup button,
explained later in this material.

Task

Tasks are placeholders that can be added to X++ code


to remind developers that something is unfinished. To
create a task, use a single line comment, followed by
the word ToDo and a description of the task. For
example:
// ToDo Add validation code

1-6

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


The Compiler window contains the following features:

Filter buttons: At the top of the window, there are buttons to toggle
the four different compile result types on and off. Toggling the result
type off will remove results of that type from the Compiler Output
window's list.

Reset button: This button will reset the contents of the Compiler
Output window.

Edit button: This button will open the X++ editor or Property sheet
corresponding to the selected compile result.

Import/Export button: This button allows compile results to be


exported to an HTML file, or imported into the Compiler Output
window from an HTML file.

Setup button: This button accesses forms where the Compiler


Output window parameters can be set for the user. These include
settings such as the Diagnostic level of the compiler, and which Best
Practices will be enforced.

Debugger
Microsoft Dynamics AX includes a powerful stand-alone debugging tool for
X++ code. Use the Debugger to debug X++ code running on the:

Microsoft Dynamics AX Client

Microsoft Dynamics AX Object Server (AOS)

NOTE: Managed code and X++ compiled into Intermediate Language (IL) are
debugged using the Visual Studio debugger. This topic will be covered in the
Visual Studio Integration chapter of the Development III course. This topic only
covers debugging standard X++ code.
Use the Debugger to:

Run a program to a certain point and then stop at a defined


breakpoint.

Step through the program one statement at a time.

Display the call stack with code line numbers.

Watch specific variables and modify their values during execution.

Track messages being sent to the infolog.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-7

Development II in Microsoft Dynamics AX 2012


Breakpoints
Breakpoints are set on individual lines of code. This is a command to stop
program execution at that point and enter the debug mode.
When the logic flow of the code in a user's session reaches a breakpoint set by
the same user, the debug session begins and the debugger is automatically
started.
To set a breakpoint:
1. Rest the cursor within the X++ code in the editor where you want to
insert the breakpoint.
2. Click the Breakpoint button in the toolbar or press F9.
3. Click in the gray area to the left of the line of code.
The line of code is highlighted in dark red to indicate that a breakpoint is
enabled. A disabled breakpoint is indicated with a red border only. Disabled
breakpoints will not cause program execution to stop, but are useful when a
specific location needs to be remembered, perhaps to enable the breakpoint at a
later point.
Breakpoints can also be set by inserting the keyword Breakpoint into the code.
This should be used with caution, because it will mean that all users will enter the
debugger when the code reaches this point.
All these methods of settings breakpoints are shown in the following figure:

FIGURE 1.3 BREAKPOINTS IN CODE

1-8

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


To turn debugging off, you can visit Tools > Options, and select the Developer
tab. In the Debug field, select None. When you set a breakpoint in code, this field
will automatically be set back to When Breakpoint.
Breakpoints are only recognized on the tiers (client or server) that have been
configured to recognize them. Code running on the client tier will always stop at
a breakpoint in a user's session, when the user has debugging turned on. Code
running on the server tier will only stop at a breakpoint when the AOS has
specifically been configured to enable breakpoints. This is a setting on the
Microsoft Dynamics AX Server Configuration Utility.
The Debugger can display up to six information windows. The windows display
detailed information about the current state of the executing code while you are
debugging. The information windows available are as follows:
Window

Description

Code

Displays the X++ code currently being debugged. The red


dot indicates where the breakpoint is inserted. The yellow
arrow indicates the line that is being executed. The arrow
can be dragged to a different line of code so that code is
either re-executed or skipped.

Variables

Displays the value of the variables. Modified variables


appear in different colors to indicate change. Users can alter
the value of variables in the debugger to see how the
program would run under different conditions.

Call Stack

Indicates which method is currently being debugged.


Double-clicking a method further down the stack will take
the Code window to that method.

Watch

Contains a user-defined range of variables. The variables


can be dragged and dropped from the Variables window or
the Code window.

Breakpoints

Displays the list of currently defined breakpoints with their


enabled status and line number.

Output

Displays separate views of text written to the window from


X++ code and kernel code. These views organize
information sent to the Output window.

HINT: The Microsoft Dynamics AX Debugger Help Guide can be accessed


directly by pressing F1 in the debugger. This guide lists keyboard shortcuts that
make it easier and faster to use the debugger.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-9

Development II in Microsoft Dynamics AX 2012


Use the toolbar located above the Output window to navigate through the code
and perform other actions.

FIGURE 1.4 DEBUGGER TOOLBAR

Moving the pointer over these buttons reveals the button's function and a
keyboard shortcut.
The more generally used buttons are described in the following table, together
with the keyboard shortcut:
Button

Keystroke

Description

Go

F5

Continues the execution.

Stop
Debugging

Shift + F5

Terminates the execution at the current


line.

Insert/Remove
Breakpoint

F9

Inserts or clears a breakpoint.

Enable/Disable
Breakpoint

Ctrl + F9

Enables or disables a breakpoint.

Remove all
breakpoints

Ctrl + Shift +
F9

Clears all breakpoints.

Step Over

F10

Steps to the next line of code in the


current method.

Step Into

F11

Steps into the current line if it contains a


method call.

Step Out

Shift + F11

Steps out of the current method.

Run to Cursor

Ctrl + F8

Continues the execution until reaching the


location of the cursor in the Source
window.

By default, for performance reasons, debugging in code that is executed on the


AOS is disabled. During development it is often required to debug this code. The
following procedure will enable code run on the AOS to be debugged.
1. Close the Microsoft Dynamics AX client
2. Click Start > Administrative Tools > Microsoft Dynamics AX
2012 Server Configuration
3. Click Manage > Create Configuration
4. In the Configuration Name, enter a name, for example AOS_Debug.
5. Click OK
6. Check the box Enable breakpoints to debug X++ code running on
this Server

1-10

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


7. Click Apply
8. Click Yes to restart the AOS service. This may take one or two
minutes.
9. Click OK to close the Server Configuration Utility.
10. Restart the Microsoft Dynamics AX client.

Demonstration: Using the Debugger


Perform the following steps to use the debugger.
1.
2.
3.
4.
5.

6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.

Open the AOT.


Expand Tables > SalesLine > Methods
Double-click the method ItemIdChanged.
Position the cursor on the folloing line of code
this.initfromInventTable(this.inventTable(), _resetPrice);
Press F9 to set a breakpoint. The line of code should be highlighted
in red to indicate a breakpoint has been set. F9 will toggle this
breakpoint on and off.
An infolog message may appear warning you that debugging is not
enabled on the server. If it does, click Close.
Close the X++ editor.
In the Application workspace, click on Sales and marketting.
In the Common section click on Sales orders > All sales orders.
Click New > Sales Order.
Select a customer account.
Click OK.
Click the drop down button on the Item number field and select an
item.
The debugger should start.
Look at the windows that are available.
In the Variables window, find the variable this.
Press F10 to step through the code.
Note how the field values change and are highlighted in red.
Press F5 to run the code and stop debugging.

Compare
Use the compare tool to highlight differences between versions of a single
element:

In two different layers

In an old version of an element

In two different elements

An element that will be imported

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-11

Development II in Microsoft Dynamics AX 2012


The most common use is to review differences between two layers. This is useful
when determining what was changed in a standard element. To compare two
layers, right-click the element and select Compare. Select which two layers to
compare and then click Compare.
Any element nodes that contain differences will be listed in the lower-left pane,
and the differences can be seen in the lower-right pane. The differences are color
coded to make it clear which version the differences come from.

FIGURE 1.5 COMPARE SYS TO USR

You can also use the compare tool to move code and element properties between
layers. When a difference is found, a black arrow is displayed in the left margin
of the lower-right pane. The icon will delete code from the current layer, or paste
code in to the current layer. This feature is useful when upgrading code.
NOTE: You can view code in a different layer by right-clicking the element and
selecting Layers.

Demonstration: Using the Compare Tool


Perform the following steps to use the compare tool.
1.
2.
3.
4.
5.

Open the AOT.


Expand the Classes node.
Expand the Activities class.
Double-click the Construct method.
Add the following line of code:
// Compare tool demonstration
6. Press F8 to compile and save.
7. Right-click the Activities class.
8. Select Compare to open the compare tool.

1-12

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


9. Click the Compare button.
10. Note how the tool displays differences in the color of the version the
code is in.
11. Note the icon to remove the code from the USR layer.

X++ Attributes
Microsoft Dynamics AX supports attributes being assigned to X++ code. This
allows for a rich set of metadata to be built. It describes methods and types that
are defined within X++ code.
Attributes are defined as classes that are derived from the SysAttribute class.
The following code for the SampleAttribute class is an example of an attribute
class:
public class SampleAttribute extends SysAttribute
{
str sMetadata; // A field in classDeclaration.
public str GetMetadata()
{
return sMetadata;
}
public void new(str _sMetadata)
{
super();
sMetadata = _sMetadata;
}
}

Attributes can then be used on other classes and methods. The following example
shows the structure of a new Attribute class, AuthorAttribute:
class AuthorAttribute extends SysAttribute
{
str author;
public str Author()
{
return author;
}

public void new(str _author)


{
super();
author = _author;
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-13

Development II in Microsoft Dynamics AX 2012


In the following example, AuthorAttribute is used to decorate other classes and
methods:
[AuthorAttribute("Isaac")]
public class MyClass()
{
...
}
[AuthorAttribute("Isaac")]
void MyMethod()
{
...
}

Type Hierarchy Browser


The Type Hierarchy Browser is a tool for viewing at a glance, which other
elements one element inherits from. For example, open the Type Hierarchy
Browser for the CustAccount extended data type. This can be done from the
elements context menu > Add-ins > Type hierarchy browser:

FIGURE 1.6 TYPE HIERARCHY BROWSER FOR CUSTACCOUNT

Notice that CustAccount inherits from CustVendAC, which inherits from


ExternalAccount, which inherits from the primitive string type. This is
displayed in a tabular format so that the value of properties at each level of the
hierarchy can be compared side-by-side.

1-14

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


The browser can also be used to explore the hierarchy farther down the tree. In
the tree view on the left-hand pane, expand the selected node to display all
elements that inherit it. In this example, you can expand the CustAccount node,
to display all extended data types that inherit it. The following figure shows the
same browser shown earlier in this topic. The difference now is that the
CustInvoiceAccount type is selected:

FIGURE 1.7 EXPANDING THE TYPE HIERARCHY

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-15

Development II in Microsoft Dynamics AX 2012


This tool can also be used on other elements, such as classes. When browsing the
hierarchy on classes, the blue boxes in the grid represent a method that is
overridden, or that exists only, on that class. The following figure shows a view
of the hierarchy for the SalesLineType_Sales class:

FIGURE 1.8 CLASSES IN TYPE HIERARCHY BROWSER

Type Hierarchy Context


In addition to the Type Hierarchy Browser, the Type Hierarchy Context
window can be used to view the hierarchy of an element in the AOT. The Type
Hierarchy Context window can be docked to the workspace, and will change
dynamically as AOT nodes are selected.
Open the Type Hierarchy Context window by navigating to: Tools > Type
Hierarchy Context.
With the Type Hierarchy Context window open, select a few different nodes in
the AOT, and notice how the window changes its contents based on the selected
node.

1-16

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


The following figure shows a view of the Type Hierarchy Context window,
with the SalesLineType_Sales class node selected in the AOT:

FIGURE 1.9 TYPE HIERARCHY CONTEXT

Each of the nodes in the Type Hierarchy Context window is also a hyperlink
that will open the Type Hierarchy Browser for an element.

Reverse Engineering
Reverse engineering is used by partners to easily retrieve detailed information
about the structures and relationships of the Microsoft Dynamics AX business
logic and data model. The goals of reverse engineering are to extract
relationships, and integrate and view collections in Microsoft Office Visio as
UML diagrams.
The feature handles both reverse engineering of the data model and the object
model.
You can use the Reverse Engineering tool to visualize data and object models
generated from projects in Microsoft Dynamics AX. These models are created as
Microsoft Visio documents.
To open the Reverse Engineering tool, right-click a project and select Add- ins >
Reverse engineer.
The information Microsoft Dynamics AX provides Visio depends on whether
you are creating a data or an object model from a project. The following table
shows what is provided for each model type:
Data Model

Object Model

Tables

Table Group property

Table Fields

Table Index information

Table Methods and parameters

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-17

Development II in Microsoft Dynamics AX 2012


Data Model
Classes (extended and referenced)

Object Model

All Extended Data Types

All Base Enums

All X++ Data Types

Procedure: Reverse Engineering an Object Model


Perform the following steps to generate an object model that is based on elements
included in a project.
1. Create a project.
2. Drag AOT elements into the project you want to reverse engineer
into an object model.
3. Right-click the project and select Add- ins > Reverse engineer.
4. Click Visio UML Object model to create a UML object model.
5. Select a name and path for the file and then click OK.
6. From Microsoft Visio, drag object nodes into the center grid to lay
out the desired model.

Procedure: Reverse Engineering a Data Model


Perform the following steps to generate a data model that is based on elements
included in a project.
1. Create a project.
2. Drag the AOT elements into the project you want to reverse engineer
into a data model.
3. Right-click the project and select Add-ins > Reverse engineer.
4. Click Visio UML Data model to create a UML data model.
5. Select a name and path for the file and then click OK.
6. From Microsoft Visio drag table nodes into the center grid to lay out
the desired model.

1-18

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++

Best Practices
Best practices involve understanding all the things that you should do and
distinguishing them from the things that you can do.
Best Practices in Microsoft Dynamics AX apply to programming in a standard
application, certified solutions, and they are recommended for any Microsoft
Dynamics AX partner or an end-user enhancing or customizing Microsoft
Dynamics AX.
Some benefits of using best practices include:

They guarantee consistency throughout the code. This lets other


developers more easily read and understand your code.

Code is more secure.

There is no redundant code.

Upgrading is easier and quicker, and has less risk of errors.

Refer to the "Microsoft Dynamics AX Developer's Help" for detailed information


on best practices.

Naming Conventions
Naming conventions contribute to consistency and to making the application
easier to understand.
Where you can, application element names should be constructed hierarchically
from three basic components:
{business area name} + {business area description} + {action performed (for
classes) or type of contents (for tables)}
Examples:

CustJournalPrintOutInvoice

PriceDiscAdmDelete

PriceDiscAdmSearch

PriceDiscAdmName

PriceDiscAdmTrans

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-19

Development II in Microsoft Dynamics AX 2012


Additionally:

All names must be in U.S. English.

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 must be spelled correctly.

Names must be used consistently.

All texts that appear in the user interface must be defined by using a
label.

Do not begin a name with nonsensical or confusing prefixes, such as


"aaa" or "CopyOf".

Do not begin a name with "DEL_" unless it is a table, extended data


type or enum, and it is needed for data upgrade purposes - doing this
may cause unexpected results.

Code Placement
The placement of code depends on the code you are writing. The preferred
procedure in an object-oriented programming language is to place code in a class
that can be reused and called when it is needed.
You can place code in classes to have better control over where the code is
executed. Performance considerations frequently dictate where code should run,
and so controlling this is desirable. Code included in forms always runs on the
client, and this could cause excessive client/server communication where it might
not be necessary.
When deciding where to place code, ask the following questions:

Is the code related to the form's appearance or to the data that is


entered through the form?

Can I use the code's functionality elsewhere in the application or in a


different application?

Does the code execute on the client or on the server?

BEST PRACTICE: Always place the code nearest to the source so that it can be
more easily manipulated. For example, code that manipulates a table should be
placed in that table's methods.

1-20

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++


Comments
A best practice for all programming is to consistently use comments. It is
important when developing X++ programs in Microsoft Dynamics AX to use
comments and document what the code does and how parameters are used. It is
also good to know who made the change and why. When upgrading code, you
have to decide whether to merge code and if this is the case, how to merge it;
comments are useful to help determine why a code change is made. Note the
following about how to use comments:

Comments can be inserted directly into the lines of code.

Comments are ignored by the compiler.

Comments turn the code green in the editor.

Some of the comments include the following:

Single line "//"

Block comments "/* */"

To do comments "TODO." To do comments appear in the compiler's


Tasks tab page.

XML documentation comments

// This is a single line comment


/* This is a block comment because
It contains more than one line */
/// <summary>
/// Comment where XML tags distinguish sections.
/// </summary>

The preceding XML documentation comments can be used to build XML


documents that contain developer documentation. The XML documentation
comments are also used to display "hover-over" help in the X++ editor. To
extract an XML documentation file from code, right-click a development project
node, and select Add-ins > Extract XML documentation.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-21

Development II in Microsoft Dynamics AX 2012

Lab 1.1 - Print to the Screen


Scenario
The client wants you to demonstrate how to print a message to the screen. Create
a job that prints a message to the screen.

Challenge Yourself!
Create a job that prints the message "Microsoft Dynamics AX is fantastic."

Step by Step
1.
2.
3.
4.

Open the AOT.


Right-click the Jobs node and select New Job.
Rename the job.
Add the following code.

info("Microsoft Dynamics AX is fantastic.");

5. Compile (press F7 or click the Compile button on the toolbar).


6. Run the job (press F5 or click the Go button on the toolbar).

1-22

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++

Lab 1.2 - Debug the Job


Scenario
The client wants you to verify the code executes without errors. Debug the job
that you created in the previous lab.

Challenge Yourself!
Set a breakpoint in the code in the job from the previous lab. Run the code and
step through it.

Step by Step
1. Set a breakpoint in your job on this line of code:
static void <your jobname>(Args _args)
2. Save the code by using a keyboard shortcut.
3. Run the code.
NOTE: You should enter the Microsoft Dynamics AX Debugger at this point. If
not, ask your instructor.
4. Step through the code by using the icon on the toolbar or F11.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-23

Development II in Microsoft Dynamics AX 2012

Lab 1.3 - Create a Data Model


Scenario
You have been asked to evaluate the Project Accounting data model to prepare
for required customizations according to customer requirements.

Challenge Yourself!
Make the data model for the Project Accounting module in Microsoft Visio by
using the Reverse Engineering tool in Microsoft Dynamics AX.

Step by Step
1.
2.
3.
4.
5.
6.
7.
8.
9.

1-24

Create a new Project.


Rename it to Reverse_Engineering.
Open the Reverse_Engineering project.
Open the AOT in another window and expand the Tables node
Drag-and-drop some project tables (tables starting with Proj) from
the AOT, to the Reverse_Engineering project.
Right-click the Reverse_Engineering project root node.
Select Add-ins > Reverse Engineer. Ensure that the Data model
option is marked.
Enter the path for the Microsoft Visio file.
Once the file is generated in Microsoft Visio, drag the tables to the
workspace and show the relationships.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++

Lab 1.4 - Create an XML Developer Document


Scenario
You have been asked to create developer documentation for the Credit Limit
modifications made in the standard Microsoft Dynamics AX application.

Challenge Yourself!
Create an XML file by using the XML documentation generation, for the Credit
Limit development project.

Step by Step
1. Open the development project tree.
2. Find the Credit Limit project.
3. Right-click the project, and select Add-ins > Extract XML
documentation.
4. Enter a file name.
5. Click OK.
6. Click Close to close the infolog window.
7. Review the file created.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-25

Development II in Microsoft Dynamics AX 2012

Summary
This lesson introduced some development tools that you will use to make
modifications to Microsoft Dynamics AX. You learned how to use the X++
editor to write code; how to compile code and review errors with the Compiler;
and how to create breakpoints and step through executing code with the
Debugger. Other tools like the Compare, Type Hierarchy Browser, Type
Hierarchy Context, and Reverse Engineering tools were also introduced.
The next lesson will show how to use these tools by creating a Calculator Class
that uses four basic methods.

1-26

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++

Test Your Knowledge


Test your knowledge with the following questions.
1. What are the three main Object-Oriented Programming components?

2. What are the functions of the six Debugger window panes?

3. What do you use the X++ editor for?

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-27

Development II in Microsoft Dynamics AX 2012

Quick Interaction: Lessons Learned


Take a moment and write down three key points you have learned from this
chapter
1.

2.

3.

1-28

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 1: Introduction to X++

Solutions
Test Your Knowledge
1. What are the three main Object-Oriented Programming components?
MODEL ANSWER:
Classes are blueprints that describe the objects derived from them. A class is
a model classification of the methods and variables in a specific type of
object. Objects are instances of classes. Each instance has data members and
logic (methods) defined in the class. Methods are functions (subroutines)
associated with a class or an object. An object implements its behavior with
methods.
2. What are the functions of the six Debugger window panes?
MODEL ANSWER:
The Code window pane displays the X++ code that is currently being
debugged. The Variables window displays the value of the variables in the
current block of code. Modified variables appear in different colors to
indicate change. The Call Stack window tells you which method is currently
being worked on. The Watch Status window displays a user-defined range of
variables. The Breakpoint window consists of a header with two columns and
the list of currently defined breakpoints. The Output window in the Microsoft
Dynamics AX Debugger has separate views that display text written to the
window from X++ code and kernel code. These views organize the
information that is sent to the Output window.
3. What do you use the X++ editor for?
MODEL ANSWER:
The X++ editor is used for editing and creating X++ code. This editor
contains many functions in the toolbar, through keyboard shortcuts, and also
by using the context (right-click) menu. The X++ editor has two panes: the
left side shows a list of the current methods and the right side shows the
current X++ code.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

1-29

Development II in Microsoft Dynamics AX 2012

1-30

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements

CHAPTER 2: X++ CONTROL STATEMENTS


Objectives
The objectives are:

Declare and use extended data types for variables.

Use the various operators available in X++.

Control program flow using conditional statements in X++.

Repetitively call the same blocks of code by using Loop statements.

Use standard functions that are built in to the application.

Use output commands to display data and messages to the user.

Introduction
This course explains how to use control statements in X++. These statements
control the logic flow in the program. This course also describes how to use some
built-in functions in Microsoft Dynamics AX to communicate with the end-user.

Scenario
Isaac, the Systems Developer, is implementing a project that requires a
modification to code. He has been asked to become familiar with the typical
statements in X++ used to control program flow, and to communicate with the
user.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-1

Development II in Microsoft Dynamics AX 2012

Introduction to Variables
Variables hold data when a block of code executes. Variables all have scope.
Scope is the area where the variable can be accessed. Some different types of
scope include:
Scope

Description

Global (to a class)

These are variables defined in the classDeclaration


of a class.

Local (to a method)

These are variables defined in a method of a class.

Local (to an embedded


function)

These are variables defined in a function embedded


in a method of a class.

Use the type of variable that matches the type of data that you want to store. You
can name the variable, as long as you do not use names the system already uses,
such as commands or keywords. A list of reserved words is located in the
Developer Help under the "Keywords" lesson.
BEST PRACTICE: Do not use names like string1. Always give a variable a
meaningful name so its use is easier to identify when reading the code.

Declaration
All variables must be declared before use. When a variable is declared, a small
amount of memory is reserved. The syntax of the declaration is the same,
whether it is a simple variable or an object variable.
You cannot mix variable declarations with other X++ statements. Variables must
be declared before the statements.
There are two rules to use when declaring variables:

Declare all variables before anything else in the code.

Use a semicolon after each declaration.

You might want a variable to have a value other than the default when the
variable is declared. X++ supports initialization of variables in the Declaration
statement. Initialization is performed by adding the assignment-statement to the
variable declaration. For example:
int a = 10; // a is assigned the value 10

Simple Data Types


X++ implements primitive data types that can be used to declare variables in
X++ code. You can also create Extended Data Types on the basis of primitive
types; this is discussed in the Development I in Microsoft Dynamics 2012 course.

2-2

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


The following table provides an overview of the simple data types available in
Microsoft Dynamics AX:
Data Type

Description

Example

Declaration
Keyword

String

A string is a number of
characters. X++ supports several
types of strings: Left aligned,
right aligned, fixed length or not
fixed length. The maximum
length of a string is 999
characters.

Name

str

Integer

An integer, also named a natural


figure, is a number without a
decimal point.

1090

int

Real

Reals, also named decimals, are


numbers with a decimal point.

3.14

real

Date

The date type contains day,


month, and year.

10\29\1978

date

UTC
DateTime

Contains year, month, day, hour,


minute and second.

9/28/2008
07:11:02 am

utcDateTim
e

Enum

Enum values are represented


internally as integers. The first
literal has the number 0, the next
number 1, the next number 2,
and so on. You can use enums as
integers in expressions.

NoYes

Must be
declared as
a Base
Enum first

Boolean

Booleans can only contain the


values false and true. The enum
values false and true are
predefined in X++ and
recognized by the compiler.

TRUE

boolean

Time

Contains hours, minutes, and


seconds. To declare a time, use
the system type timeOfDay.

15:23:08

timeOfDay

GUID

Global Unique Identifier


(GUID) is a reference number
which is unique in any context.

{3F2504E04F89-11D39A0C0305E82C3
301}

guid

Int64

A large integer, represented by


64 bits.

5637144579

Int64

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-3

Development II in Microsoft Dynamics AX 2012


The simple variable declaration is frequently used.
The syntax for the simple variable declaration is as follows:
dataType

variableIdentifier;

The data type can be any of the data types in X++. Here are some examples:
int
real
str
str 30
date
boolean

integerVariable;
realVariable;
unboundStringVariable;
boundStringVariable; // max of 30 chars
dateVariable;
booleanVariable;

When declaring a variable, you can also declare them as an extended data type.
This is a good practice because it can highlight errors in code at compile time
when a variable is used incorrectly.
It is common to name the variable the same as the extended data type, when
possible.
custAccount
transDate
amountMST

custAccount;
transDate;
amountDebit, amountCredit;

Initializing Variables
The following statements show how to declare the variables for use later in the
code. You can declare several variables of the same type with different names.
You can also assign a value to the variable when you declare it or later in the
code.
int
int

2-4

counter, toCount;
fromCount = 1;

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


Composite Data Types
In addition to the simple data types, you can use composite data types when
declaring variables.
The following composite data types are available:
Data type

Description

Array

An array is a list of items with the same data type and the
same name; only the index differs.

Container

A container is a dynamic list of items that can contain


primitive data types and some composite data types.

Classes

A class is a type definition that describes both variables


and methods for instances (objects) of the class.

Tables

All tables defined in the database (in the data dictionary)


can be handled as class definitions.

Arrays
Arrays can be declared by adding brackets ( [ ] ).
You can set the maximum number of array elements by putting the number in the
brackets.
Array values can be set by specifying the index when assigning the value.
real
real

realUnlimtedArray[]; // Unlimited index values


realLimitedArray[10]; // maximum of 10 values

realLimitedArray[2] = 3.142;

Containers
A container variable can contain different types and values of simple and
extended data types, including arrays and other container variables. Classes
cannot be put into containers.
There are many functions that manipulate container variables. The following
functions are available:
Function

Description

conPeek

Returns the value being held in a specific position in the


container.

conDel

Removes a value from a specific position in the container.

conNull

Returns an empty container.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-5

Development II in Microsoft Dynamics AX 2012


Function

Description

conFind

Finds the position in the container that a certain value is


being held (if found).

conIns

Inserts a value into a specific position in the container.

conPoke

Replaces the value being held in a specific position in the


container, with a new value.

conLen

Returns the number of elements in the container.

The following examples have a container variable that contains four values,
including three different data types.
container c;
// the container is declared
int
i, j;
str
txt;
c = [10, 20, "test"]; // the container has 3 values set
print conPeek(c, 3);
// the third element is printed
[i,j,txt] = c; // other variables are set from the
container

Operators
Operators are used to manipulate variable and field values and to control the
logical program flow based on the values in variables and fields. The following
types of operators are available.

Assignment operators modify the contents of a variable or field.

Arithmetic operators perform mathematical operations on the values


in a variable or field.

Relational operators evaluate how two values relate to one another


and return either True or False according to the result.

Assignment Operators
Assignment operators modify the contents of a variable or field. The following
table defines available operators.

2-6

Operator

Description

Assigns the expression on the right of the equal sign to the


variable on the left.

+=

Increments the variable on the left by the value on the right.

++

Increments the variable on the left by one.

-=

Decrements the variable on the left by the value on the right.

--

Decrements the variable on the left by one.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


Arithmetic Operators
Arithmetic operators perform calculations in X++. Arithmetic operators are used
like relational operators except for '~, ++, --, +=, and -='. The following table
defines available arithmetic operators:
Operator

Term

Description

Plus

Adds expression1 to expression2.

Minus

Subtracts expression2 from expression1.

Multiply

Multiplies expression1 with expression2.

Divide

Divides expression1 with expression2.

DIV

Integer
division

Performs an integer division of expression1


with expression2.

MOD

Integer
remainder

Returns the rest of an integer division of


expression1 with expression2.

Not

Unary operator: performs a binary notoperation.

&

Binary
And

Performs a binary and-operation on expression1


and expression2.

Binary
XOR

Performs a binary XOR-operation on


expression1 and expression2.

Binary Or

Performs a binary or-operation on expression1


and expression2.

<<

Left shift

Performs expression2 left shift (a multiplication


with two) on expression1.

>>

Right shift

Performs expression2 right shift (a division by


two) on expression1.

Ternary
operator

Takes three expressions: expression1 ?


expression2 : expression3. If expression1 is
true, expression2 is returned otherwise
expression3 is returned.

The following are some examples of these arithmetic operators. For all examples,
the variable 'i' is an integer.
Evaluated Expression

Return Value

i++;

Increments the i variable by one.

i--;

Decrements the i variable by one.

i += 2;

Increments the i variable by two every time.

i -= 3;

Decrements the i variable by three every time.

i = 3 << 3

i = 24 (i = 3*2*2*2)

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-7

Development II in Microsoft Dynamics AX 2012


Evaluated Expression

Return Value

i = 24 >> 2

i = 6 (i = 24/2/2)

i = 80 DIV 13

i = 6 (6 is the largest number that 13 can be


multiplied by, where the result is less than or
equal to 80. In this case, 6*13 = 78, remainder
2)

i = 80 MOD 13

i = 2 (2 is the remainder after dividing 80 by


13)

NOTE: View more examples of arithmetic operators in the "X++ Online Help
Guide."

Relational Operators
Relational operators, except for '!', are placed between two expressions. The
following table defines available relational operators:

2-8

Operator

Term

Description

==

equal

Returns true if both expressions are equal.

>=

greater than
or equal

Returns true if expression1 is greater than or


equal to expression2.

<=

less than or
equal

Returns true if expression1 is less than or equal


to expression2.

>

greater than

Returns true if expression1 is greater than


expression2.

<

less than

Returns true if expression1 is less than


expression2.

!=

not equal

Returns true if expression1 differs from (not


equal to) expression2.

&&

and

Returns true if both expression1 and


expression2 are true.

||

or

Returns true if expression1 or expression2 or


both are true.

not

A unary operator. Negates the expression.


Returns true if the expression is false, and false
if the expression is true.

like

like

Returns true if expression1 is like expression2.


This can use * as a wildcard for zero or more
characters and ? as wildcard for one character.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


The following are examples using relational operators and their return values:
Evaluated Expression

Return Value

'abcdef' like 'abc*'

TRUE: the * is equal to any string of characters.

'abcdef' like 'abc?'

FALSE: the ? is equivalent to one character.

9 != 10

TRUE: these values are not equal to one


another.

(10 > 9) && (11 <= 11)

TRUE: both expressions are true.

!('abc' = = 'def') || (8 > 9)

TRUE: the first expression returns true.

Operator Precedence
You can use X++ to create complex statements using multiple operators when
data types on all parts of the statements are equivalent. When multiple operators
are used in one statement, precedence for the operators must be in place for
statement evaluation. The following table lists the precedence for operators. The
highest precedence is at the beginning of the table; precedence gets lower as you
move down the table.
Operator Type

Operator Syntax

postfix operators

[] . (params) expr++ expr--

unary operators

++expr --expr +expr -expr ~ !

creation

new (type)expr

multiplicative

*/

additive

+-

relational

< > <= >=

equality

== !=

bitwise AND

&

shift

<< >>

bitwise exclusive OR

bitwise inclusive OR

logical operators (AND, OR)

&& ||

conditional

?:

assignment

= += -=

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-9

Development II in Microsoft Dynamics AX 2012

Conditional Statements
Conditional statements in programming define conditions under which certain
functions are performed. Conditional statements use logical expressions that are
evaluated and return a value of either true or false. There are three primary
conditional statements:

If statement

Switch statement

Ternary operators

All these statements are evaluated using operators.

If
The if statement is the simplest control statement. It checks whether a condition
is true or false. If the condition is satisfied, all the code within the braces '{}' is
executed. The syntax for an if statement is as follows:
if (condition)
{
//if true these statements are executed
}

The following is an example of an if statement. If the variable a is greater than


10, the value of a will be printed to the screen.
if (a > 10)
{
print a;
}

The following is an example of an if statement using multiple expressions to


evaluate the condition.
if((a < 5) || (a > 10))
{
print a;
}

2-10

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


If...else
An if statement checks for only one possibility and ignores all other conditions.
An ifelse statement checks one condition and if true, the block of code is
executed. Otherwise, an alternative statement is executed. The syntax for an
ifelse statement is as follows:
if (condition)
{
//if true these statements are executed
}
else
{
//if false these statements are executed
}

int
int
int

i = 12;
j = 10;
max;

if (i > j)
{
max = i;
}
else
{
max = j;
}

The previous conditional formulas allow for only two alternative outcomes. A
program might have to check more than two alternatives. To check for multiple
alternatives, you can use an ifelse...if statement. The syntax for this statement
is as follows:
if (condition1)
{
//statement1
}
else
{
if (condition2)
{
//statement2
}
else
{
//statement3
}
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-11

Development II in Microsoft Dynamics AX 2012


The system checks condition 1 first, and if satisfied, statement1 is executed. If
the condition 1 is not satisfied, it moves to condition2. If condition2 is satisfied,
statement2 is executed. If condition2 is not satisfied, then statement3 executes.
You can use as many conditions as necessary.
You might need to have a condition in a condition. You can do this using nested
if statements.
A mathematics teacher uses the following criteria to determine who passes or
fails the class:

Pass the final exam

Pass the homework sections

Check the logic in the following order:


1. If the student has failed the exam, then the student fails the course.
2. If the student has passed the exam, then check the student's
homework sections.
3. If the student has passed the exam and the homework sections, the
student passes the course.
4. Otherwise, the student fails.
boolean
boolean
str

passExam = true;
passHomeWork = false;
studentStatus;

if (passExam == true)
{
if (passHomeWork == true)
{
studentStatus = "Passed";
}
else
{
studentStatus = "Failed";
}
}
else
{
studentStatus = "Failed";
}

Ternary Operator
This conditional statement behaves exactly like an ifelse statement. The main
reason to use the ternary operator is convenience in coding. Its syntax is as
follows:
condition ? statement1 : statement2;

2-12

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


The condition is checked first and if true, statement1 is executed, if false,
statement2 is executed. However, the two expressions following the question
mark (?) must be of the same data type.
This example using the ternary operator, is equivalent in logic and results to the
previous example using the if...else statement.
int
int
int

i = 12;
j = 10;
max;

max = i > j ? i : j;

Switch
A switch statement acts as a multi-branch control statement that defines an
expression and whose result leads to a specific program execution. The switch
statement considers the result and executes code, depending on possible
outcomes of the expression. These are known as cases. Each of these cases is
listed in the body of the statement.
Following the colon after each case are statements that execute if the expression
satisfies the case. There can be any number of statements following a case in a
switch statement. The body of a switch statement is enclosed in braces '{}'. The
following shows the syntax for a switch statement:
switch (expression)
{
case 'Choice1':

case 'Choice2':

case 'Choice3':

Statement1;
Statement2;
break;
Statement3;
break;
Statement4;
Statement5;
Statement6;
break;

default : DefaultStatement;
}

The break; statement tells the program to leave the switch statement and
continue immediately after the switch. This can also be used elsewhere in X++
coding. The default case executes if the result of the expression does not match
any of the cases. Using the default case is optional.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-13

Development II in Microsoft Dynamics AX 2012


The following example compares a switch statement with an ifelse statement.
For these examples, students receive a score from a test. The score must have a
corresponding letter grade. The scores can only be 90, 80, 70, and so on.
int score = 80;
str grade;
str message;
switch (score)
{
case 90 :
case 80 :
case 70 :
case 60 :
default :
}

grade =
message
break;
grade =
message
break;
grade =
message
break;
grade =
message
break;
grade =
message

"A";
= "Excellent";
"B";
= "Good";
"C";
= "Average";
"D";
= "Poor";
"Failed!";
= "You need to study more!" ;

This example produces the same result as the previous example, but uses if...else
statements instead of the case statement. Note the number of lines of code and
the ease of reading the code in each case.
int score = 80;
str grade;
if (score == 90)
{
grade = "A";
}
else
{
if (score == 80)
{
grade = "B";
}
else
{
if (score == 70)
{
grade = "C";
}
else
{

2-14

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements

if (score == 60)
{
grade = "D";
}
else
{
grade = "Failed!";
}

As illustrated on the previous page, the switch statement simplifies the code and
makes the program flow more efficiently. Another advantage of using a switch
statement is allocating multiple results of the expression to one outcome or case.
The following example shows the use of multiple expressions in a switch
statement.
str color = "red";
str colortype;
switch (color)
{
case "red", "yellow", "blue" :
colortype = "Primary Color";
break;
case "purple", "green", "orange" :
colortype = "Secondary Color";
break;
default : colortype ="Neither Primary or Secondary";
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-15

Development II in Microsoft Dynamics AX 2012


This example produces the same result as the previous example, but uses if...else
statements instead of the case statement. Note the number of lines of code and
the ease of reading the code in each case.
str
str

color = "red";
colortype;

if ((color =="red")
|| (color =="yellow")
|| (color =="blue"))
{
colortype ="Primary Color";
}
else
{
if ((color =="purple")
|| (color =="green"')
|| (color =="orange"))
{
colortype ="Secondary Color";
}

else
{
colortype ="Neither Primary or Secondary color"
}

Loops
Repetitive statements, also known as loops, conditionally control data input and
output. There are three main loops in X++:

While loop

Do while loop

For statement

While
The while loop evaluates a condition and executes statements, depending on
whether the condition is satisfied. The loop continues to check the condition, and
as long as the condition is true, it continues to execute the statements. As soon as
the condition becomes false, the statement is exited. The syntax is as follows:
while (condition)
{
//statement;
}

2-16

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


This is a simple while statement that counts from 1 to 5.
int counter = 1;
while (counter <= 5)
{
print counter;
counter ++;
// This increments the counter by 1
}
pause;

Result:
1
2
3
4
5
HINT: The previous example uses the counter++ which can increment any
integer by 1. You can also set the increment to any value by using the
variable+=<# to increment> syntax. For example:
counter+=2; //This increments the counter variable by two every time.
Notice the condition is evaluated before the statements are executed. In the
previous example, it means that if the counter variable is greater than five when it
reaches this loop, it does not execute. Therefore, a while statement can be
executed zero or more times.

Do...while
The function of a do while statement is almost identical to the while statement.
The main difference is that the condition is evaluated after the statement
executes. The effect is that the loop always runs at least one time. The following
is the syntax for a do while statement:
do
{

//statement;
}
while (condition);

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-17

Development II in Microsoft Dynamics AX 2012


For
The for statement uses an incrementing counter variable, and a condition, to
determine the how long it will continue to loop. The parameters in a for
statement include three elements:

The initial value of the variable.

The condition under which the loop will continue.

The amount the variable is increased or decreased by.

The syntax can be defined as follows:


for ( initial value ; condition ; increment)
{
//statement;
}

For loops are frequently used when navigating through an array. The following
is an example of how to use a for loop to print each element of a string array
called 'abc' that contains 10 strings:
for (counter = 1; counter <= 10; counter++)
{
print abc[counter];
}

A for loop and a while loop perform the same function. However, the for loop is
more condensed in structure. In a while loop, if the counter variable is not
incremented, an infinite loop can occur. This is not possible with a for loop
because you receive a syntax error if that part of the condition is not qualified.

Continue and Break Statements


You can use continue and break statements within all three loops to tell the
execution to break or continue.
The break statement completely interrupts a loop at any time. The best example
of a break is in a switch statement.

2-18

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


The continue statement ignores the rest of the current loop and continues to
control the loop. The following example uses a for loop with the continue
statement to control which values print to the screen. The loop executes the print
statement for values <= 3 and >= 8.
int counter;
for (counter=1;counter <= 10;counter++)
{
if (counter > 3 && counter < 8)
{
continue;
}
print counter;
}
pause;

Result:
1
2
3
8
9
10

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-19

Development II in Microsoft Dynamics AX 2012

Lab 2.1 - Create a Times Table Using a While Loop


Scenario
Isaac has been asked to demonstrate the use of a while statement by printing out
the multiplication table for 2.

Challenge Yourself!
1. Create a job that prints the multiplication table for 2 using a while
statement.
2. Have the list contain all even numbers up to 50.
3. Use a 'counter' variable to increment every time.

Step by Step
1.
2.
3.
4.

Open the AOT.


Right-click the Jobs node and select New Job.
Rename the job.
Add the following code.

int counter = 1;
while (counter <= 25)
{
print counter * 2;
counter++;
}
pause;

5. Compile the code (press F7 or click the Compile button in the


toolbar).
6. Run the job (press F5 or click the Go button in the toolbar).

2-20

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements

Lab 2.2 - Create a Times Table Using a Do...while Loop


Scenario
Isaac has been asked to demonstrate the use of a do...while statement by printing
out the multiplication table for 2.

Challenge Yourself!
1. Create a job that prints the multiplication table for 2 using a
do...while statement.
2. Have the list contain all even numbers up to 50.
3. Use a 'counter' variable to increment every time.

Step by Step
1.
2.
3.
4.

Open the AOT.


Right-click the Jobs node and select New Job.
Rename the job.
Add the following code.

int counter = 1;
do
{

print counter * 2;
counter++;

}
while(counter <= 25);
pause;

5. Compile the code (press F7 or click the Compile button in the


toolbar).
6. Run the job (press F5 or click the Go button in the toolbar).

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-21

Development II in Microsoft Dynamics AX 2012

Lab 2.3 - Create a Times Table Using a for Statement


Scenario
Isaac has been asked to demonstrate the use of a for statement by printing out the
multiplication table for 2.

Challenge Yourself!
1. Create a job that prints the multiplication table for 2 using a for
statement.
2. Have the list contain all even numbers up to 50.
3. Use a 'counter' variable to increment every time.

Step by Step
1.
2.
3.
4.

Open the AOT.


Right-click the Jobs node and select New Job.
Rename the job.
Add the following code.

int counter;
for(counter = 1; counter <= 25; counter++)
{
print counter * 2;
}
pause;

5. Compile the code (press F7 or click the Compile button in the


toolbar).
6. Run the job (press F5 or click the Go button in the toolbar).

2-22

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements

Built-in Functions
Microsoft Dynamics AX contains many built-in functions to help in X++
development. These functions perform mathematical operations, convert data
types, return system values, and so on.
Built-in functions can be used anywhere in X++ code. These functions can be
typed manually or accessed by using the context (right-click) menu in the Code
Editor and selecting List Built-in Functions, or by pressing Shift+F4.

FIGURE 2.1 BUILT-IN FUNCTIONS LISTING

To use a function, click it. The function is placed in the code where the pointer is
located.
This example uses a function that returns a subset of a string variable. The syntax
for the function is as follows:
str subStr(str text, int position, int number);
The following table describes the components of the function:
Component

Description

str substr

Specifies the return type of the function (string) and the


name of the function (subStr).

str text

The original text string.

int position

Indicates the position where the sub-string starts.

int number

Designates how many characters are included in the substring.

str letters;
letters = "ABCDEFG";
print subStr(letters, 2, 4);
print subStr(letters, 5, -3);
pause;

Result in the message window:


BCDE
CDE
The negative number causes the characters to be selected backward from the
position.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-23

Development II in Microsoft Dynamics AX 2012

Communication Tools
Communicating with the end-user is important and critical for an application to
run correctly. The main types of communication include:

Forms and reports used for input and output of larger amounts of
data.

Print statements, Infologs and dialog boxes generally used for


specific data input and output.

This lesson discusses how to use the print statement, create dialog boxes and
Infologs. Forms and reports are covered in more detail in the next development
course.

Print...Pause
When the compiler reaches a print statement, it returns whatever value or
variable value that immediately follows the print syntax. The following is an
example of the print statement:
print "This is a test message.";
pause;

The pause line freezes the output text on the screen after the code runs so that it
is easier to read. The pause statement causes a message box to pop up. It lets the
user continue or end code execution.
The print statement should not be used within the actual application business
logic. It is used only as a programmers tool to display data or values while
developing and debugging code.

Boxes
Boxes display brief messages to application users. There are many box types and
each has their own box method.
Methods in the box class take the following parameters:

The main text

The title bar text

Help text

The following is an example of an information box and how the parameters are
used:
Box::info("Main Text", "Title", "This is the help text");

2-24

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


The following figure shows the resulting window.

FIGURE 2.2 INFORMATION BOX EXAMPLE

The string "This is the help text" appears in the status bar at the bottom of the
screen.
The box class contains many methods that create different types of boxes. These
methods can be viewed in the AOT under Classes > Box. Many boxes only
provide output to the user, whereas other boxes accept input from the user,
depending on which button the user clicks.
Some of the more commonly used boxes are discussed in this lesson.
The warning box is used to display warning messages. The following example
shows how the warning message is used:
Box::warning("This is a warning message.", "Title text",
"Help text");

The resulting box is shown on the display.

FIGURE 2.3 WARNING BOX

The following example shows a YesNo box:


Box::yesNo("Choose Yes or No", DialogButton::Yes, "Yes No
Box Example", "Answer Yes or No");

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-25

Development II in Microsoft Dynamics AX 2012


The resulting box is shown on the display.

FIGURE 2.4 YES/NO BOX EXAMPLE

Notice the additional required parameter DialogButton::Yes. This parameter


specifies a default button. Notice on the YesNo box that the Yes button is
selected as the default.
The following is an example of how X++ accepts user input and executes
statements based on this input:
DialogButton dialogButton;
dialogButton= Box::yesNo("Choose Yes or No",
DialogButton::Yes, "Yes No Box Example");
if (dialogButton == DialogButton::Yes)
{
print "You chose Yes";
pause;
}
else if (dialogButton == DialogButton::No)
{
print "You chose No";
pause;
}

The box function returns a value of the enum DialogButton that can be used to
determine which option the user chooses.

Infolog
The Infolog is the most common method used to communicate with the user
about how a process is executed. Boxes can output a message to a user. However,
sometimes multiple messages are generated during processing. Infologs are more
suited to handle multiple messages; there are three types of messages:

2-26

Message type

Description

Information

Important information that does not require any action.

Warning

Warning when a critical situation occurs.

Error

When a fatal error occurs and a user must take action

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


The following table contains Infolog icons and a description of each method.

FIGURE 2.5 INFOLOG ICONS

Several methods exist to invoke the Infolog system.


The easiest way is to use the info (text) function. This adds the text to the Infolog
system. Any text that is added to the Infolog is displayed when the program
returns to a state of waiting for user input. This is typically at the end of a
process.
info("This is an info infolog");

The following figure shows the resulting output.

FIGURE 2.6 EXAMPLE INFOLOG BOX

Creating warning or error Infolog messages resemble the example shown


previously in this lesson. The only part of the syntax that changes is the word in
front of the parentheses. The following example shows the syntax for warning
and error Infologs:
warning("Infolog text");
error("Infolog text");

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-27

Development II in Microsoft Dynamics AX 2012


The following figure shows the error Infolog message.

FIGURE 2.7 EXAMPLE INFOLOG BOX

The Infolog system is used mostly to display multiple messages at the same time,
in tree form. The following figure shows an example of multiple messages in tree
form.

FIGURE 2.8 INFOLOG TREE

The setPrefix() function sets the label for the heading of the Infolog tree. In the
example, it specifies the label, 'Infolog Tree'. The following example shows the
syntax of this method:
setPrefix("Infolog Tree");

2-28

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


The following figure shows how adding calls to setPrefix() adds multiple levels
to the Infolog tree. The level will continue while the method the setPrefix()
statement is called in remains in scope.

FIGURE 2.9 MULTILEVEL INFOLOG

BEST PRACTICE: Use labels when possible for the text of these Infolog
messages and the SetPrefix function.

Dialog Boxes
Dialog boxes are a simplified type of form in Microsoft Dynamics AX, and they
are generated from the Dialog class. They create a dialog with the user where the
user can input values. Dialog boxes are not used in complex scenarios; forms are
the preferred method in complex situations. All dialog boxes have a standardized
form that contains an OK/Cancel option.
NOTE: The Dialog class described here is a different concept then the Dialog
Form Template available as a context-menu option on the Form node in the
AOT. This topic describes creating Dialog forms using X++ code.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-29

Development II in Microsoft Dynamics AX 2012


The following is an example of the OK/Cancel dialog box.

FIGURE 2.10 SIMPLE DIALOG BOX

The following example displays the dialog box and prints the value entered to the
screen.
static void Simple_Dialog(Args _args)
{
dialog
dialog;
dialogGroup dialogGroup;
dialogField dialogField;
dialog
= new Dialog("Simple Dialog");
dialogGroup = dialog.addGroup("Customer");
dialogField =
dialog.addField(extendedTypeStr(custAccount));
if (dialog.run())
{
print dialogField.value();
pause;
}
}

The dialog.run() method returns true if OK is clicked, and false if Cancel is


clicked.

2-30

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements

Lab 2.4 - Create a YesNo Box


Scenario
Isaac has been asked to create a job that will prompt the user to continue or
cancel. The user should be asked whether he or she wants to continue and be able
to choose Yes or No.

Challenge Yourself!
Create a new job in the AOT that contains a box where the user can decide to
continue or cancel.
1.
2.
3.

The caption on the window is "Question."


The text should be "Do you want to continue?"
The default button is "Yes."

Step by Step
4.
5.
6.
7.

Open the AOT.


Right-click the Jobs node and select New Job.
Rename the job.
Add the following code.

DialogButton dialogButton;
dialogButton = Box::yesNoCancel("Do you want to continue?",
DialogButton::Yes, "Question", "Bottom help text");

8. Compile the code (press F7 or click the Compile button in the


toolbar).
9. Run the job (press F5 or click the Go button in the toolbar).

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-31

Development II in Microsoft Dynamics AX 2012

Lab 2.5 - Create an Infolog Tree


Scenario
Isaac has been asked to create an Infolog Tree that has an Info message, a
Warning message and an Error message.

Challenge Yourself!
Create a tree of Infolog messages using a job in Microsoft Dynamics AX. The
tree should have a root node which states: "This is the Infolog Tree lab." The tree
should contain at least one of each type of message (Info, Warning and Error).

Step by Step
1.
2.
3.
4.

Open the AOT.


Right-click the Jobs node and select New Job.
Rename the job.
Add the following code.

setPrefix("This is the Infolog Tree lab");


info("Info message");
warning("Warning message");
error("Error message");

5. Compile the code (press F7 or click the Compile button in the


toolbar).
6. Run the job (press F5 or click the Go button in the toolbar).

2-32

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements

Lab 2.6 - Create a Dialog Box


Scenario
Isaac has been asked to create a dialog box that will prompt the user to enter a
customer account number and a sales order ID.

Challenge Yourself!
Create a dialog box that lets the user select a customer account number and a
sales order ID. Once the user clicks OK, show the values of each selection using
the Infolog.

Step by Step
1.
2.
3.
4.

Open the AOT.


Right-click the Jobs node and select New Job.
Rename the job.
Add the following code.

Dialog
DialogGroup
DialogField
DialogField

dialog;
dialogGroup;
dialogFieldCustAccount;
dialogFieldSalesId;

dialog = new Dialog("Simple Dialog");


dialogGroup = dialog.addGroup("Customer");
dialogFieldCustAccount =
dialog.addField(extendedTypeStr(CustAccount));
dialogFieldSalesId =
dialog.addField(extendedTypeStr(SalesId));
if(dialog.run())
{
info(dialogFieldCustAccount.value());
info(dialogFieldSalesId.value());
}

5. Compile the code (press F7 or click the Compile button in the


toolbar).
6. Run the job (press F5 or click the Go button in the toolbar).

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-33

Development II in Microsoft Dynamics AX 2012

Lab 2.7 - Use X++ Control Statements


Scenario
Isaac has been asked to create a job that will ask the user if he or she wants to
display his or her date of birth. If the user chooses Yes, the system should print
the user's name and date of birth. If the user chooses No, the system should only
print the user's name.

Challenge Yourself!
Create a dialog for the user that determines, based on input, what appears on a
screen.
1. Create a new job in the AOT and declare and initialize a
DialogButton object variable and a container data type variable.
2. The three elements of the container are your first name, last name,
and birth date.
3. The Dialog button should be a Yes No box with the text "Do you
want to display your birth date?" with Yes being the default button.
4. If Yes is clicked - first name, last name, and birth date appear.
5. If No is clicked - only first and last name appear.

Step by Step
1.
2.
3.
4.

Open the AOT.


Right-click the Jobs node and select New Job.
Rename the job.
Add the following code.

DialogButton
container

dialogButton;
nameAndDOB;

nameAndDOB = ["John","Doe",mkDate(28,9,71)];
dialogButton = Box::yesNo("Do you want to see the
birthdate?", DialogButton::Yes);
if (dialogButton == DialogButton::Yes)
{
Box::info(strFmt("%1 %2, %3", conPeek(nameAndDOB,1),
conPeek(nameAndDOB,2), date2str(conPeek(nameAndDOB,3),-1,1,-1,-1,-1,-1)));
}
else
{
Box::info(strFmt("%1 %2",conPeek(nameAndDOB,1),
conPeek(nameAndDOB,2)));
}

2-34

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


5. Compile the code (press F7 or click the Compile button in the
toolbar).
6. Run the job (press F5 or click the Go button in the toolbar).
Note the use of mkDate and strfmt functions. MkDate ("make date") returns a
date from the parameters day, month and year. Strfmt ("string format") inserts
any type of value into a string.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-35

Development II in Microsoft Dynamics AX 2012

Summary
This course introduced three conditional statements and three repetitive
statements. Depending on whether the conditions are true, different commands
can be executed.
This course also showed how the built-in functions can help when writing X++
code to perform mathematical operations, convert data types and so on.
Additionally, to communicate with the end-user, this course showed how to use
the Print Statement, the Box Class, the Infolog System and the Dialog Box.

2-36

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements

Test Your Knowledge


Test your knowledge with the following questions.
1. What are the three primary types of conditional statements in X++?

2. Which arithmetic operator would you use to output the remainder when
dividing 83 by 10 and what would the syntax be?

3. What is the main difference between using a while statement and a


do...while statement?

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-37

Development II in Microsoft Dynamics AX 2012


4. What is the function 'mthName' used for? What is its syntax? Give an
example using this function.

5. What is the syntax for the three types of messages in an Infolog?

2-38

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements

Quick Interaction: Lessons Learned


Take a moment and write down three key points you have learned from this
chapter
1.

2.

3.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-39

Development II in Microsoft Dynamics AX 2012

Solutions
Test Your Knowledge
1. What are the three primary types of conditional statements in X++?
MODEL ANSWER:
A. If Statement: This statement checks whether a condition is true or false.
If the statement is true, all the code in the braces '{}' is executed. There are
other versions of the If statement including an Ifelse, or a nested If
statement.
B. Switch Statement: This is a multi-branch control statement that defines a
condition and whose result determines the code that is executed. A switch
statement has multiple cases and for each case there are listed statements that
will be executed if that case satisfies the condition.
C. Ternary Operator: This control structure acts as an Ifelse statement. It
is primarily used because it is much more convenient to code than writing out
an Ifelse statement.
2. Which arithmetic operator would you use to output the remainder when
dividing 83 by 10 and what would the syntax be?
MODEL ANSWER:
MOD
83 Mod 10
3. What is the main difference between using a while statement and a
do...while statement?
MODEL ANSWER:
The main difference between a While statement and a Do...While statement
is that the condition is evaluated after the statements are executed in a
Do...While statement. Therefore a Do...While statement always runs at least
one time.

2-40

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 2: X++ Control Statements


4. What is the function 'mthName' used for? What is its syntax? Give an
example using this function.
MODEL ANSWER:
'mthName' is used to return the month name based on the number specifying
the month. Its syntax is as follows:
str mthName (int month);
Example
mthname(1); //returns "January"
5. What is the syntax for the three types of messages in an Infolog?
MODEL ANSWER:
info ('Infolog text');
warning ('Warning text');
error ('Error text');

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

2-41

Development II in Microsoft Dynamics AX 2012

2-42

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes

CHAPTER 3: OBJECTS AND CLASSES


Objectives
The objectives are:

Use the classes within Microsoft Dynamics AX 2012 X++


development.

Control access to methods using Access Control Method Modifiers.

Extend a class using the concept of inheritance.

Describe the differences between an object and a class.

Initialize variables in the appropriate place according to scoping


rules.

Call methods within the same class.

Use the different method types available.

Describe the similarities and differences between tables and classes.

Use the eventing publisher and subscriber model when modifying


code in the application.

Introduction
A class is a software construct that defines the data (state) and methods
(behavior) of the specific concrete objects that are subsequently constructed from
that class.
It can be thought of as a blueprint 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.

Scenario
Isaac, the systems developer, has been asked to print a name to the screen. He
would like to try some different ways of doing this in code.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-1

Development II in Microsoft Dynamics AX 2012

Classes
A class is constructed of member which can be variables or methods.

Variables are used to store the data for the class. They are specific to
an object; every object instantiated from the class declaration has its
own copy of the variable. Such variables are known as instance
variables.

Methods are the functions that operate on the data and define the
object's behavior. They are often declared to operate on the instance
variables of the class, and are known as instance methods.

A class is not an object. A class is an outline that defines how an object behaves
when the object is created from the class. Obtain concrete objects by instantiating
a previously defined class. Many objects can be instantiated from one class
definition.

Declaration of Classes
A class contains the properties, methods, and variables needed by the object.
Create a class by right-clicking the Classes node of the AOT and selecting New
Class, or by using the Class Wizard at Tools > Development Tools > Wizards.
A class always contains a classDeclaration node and two methods:

ClassDeclaration: Specifies the name of the class and necessary


variables. It can also specify inheritance.

NOTE: classDeclaration is not a method. It is a class-level scope area used to


define variables that are global to all non-static methods within the class. This
means that you can use these variables in any methods in the class, and the
variable value will be the same in each method.

New(): This method instantiates a new object. You can also assign
values to object variables using this method.
Finalize(): This method terminates the object. It is never used within
the application and exists only for convention.

These methods enable the object instantiation to occur. An infinite number of


methods can be added to a class.

3-2

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes


Demonstration: Create a Class in the Application Object
Tree
This demonstration illustrates how to create classes, add variables to the class,
and create a method in a class. Perform the following steps to create a class in the
AOT:
1. Open the AOT.
2. Locate the Classes node.
3. Right-click the Classes node and select New Class in the context
menu. A new class named Class1 is created and contains one node:
the classDeclaration node. It is empty by default. The following
figure shows how the new class looks.

FIGURE 3.1 CREATING A NEW CLASS

Demonstration: Create Variables in the Class


Perform the following steps to create variables in the class:
1. Double-click the classDeclaration node.
2. Enter the declarations between the two { } braces.

Demonstration: Create New Methods in a Class


Perform the following steps to create new methods in a class:
1. Right-click the class and select New Method.
2. Rename the method.
3. Type code between the two { } braces.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-3

Development II in Microsoft Dynamics AX 2012

Lab 3.1 - Create a New Class


Scenario
You have been asked to create a class that will print your name to the screen.

Challenge Yourself!
Create a new class that has one class variable that can hold your name. Create a
method that will set the value of the variable to be your name. Create another
new method that can print the value of the variable.

Step by Step
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.

3-4

Open the AOT.


Find the Classes node.
Right-click and select New Class.
Expand the node for the newly created class.
Double-click the classDeclaration.
Rename the class to PrintMyName.
Declare a variable of type String, called "myName".
Press F8 to compile and save the classDeclaration.
Right-click the class and select New Method.
Double-click the new method.
Rename the method to "setMyName".
Enter the code in the setMyName method shown below into your
method.
Press F8 to compile and save the method.
Right-click the class and select New Method.
Double-click the new method.
Rename the method to "printMyName".
Enter the code in the printMyName method show below into your
method.
Press F8 to compile and save the method.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes


public class PrintMyName
{
str 20
myName;
}
private void setMyName()
{
myName = "Isaac";
}
private void printMyName()
{
print MyName;
}

Method Access Control


Methods in a class are always available to other methods in the class. However
they should not always be available to methods in other classes. To control
access to a method, a methods modifier is placed in the method definition.

Modifiers
There are three modifiers available.

Public allows the method to be called from any code in the


application.

Protected allows the method to be called only by methods in the


same class or subclasses of the class in which the method is defined.

Private allows the method to be called only by methods in the same


class in which the method is defined.

When a new method is created, the default modifier of the method is Private.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-5

Development II in Microsoft Dynamics AX 2012

Lab 3.2 - Allow Access to Methods


Allow the methods created in the previous lab to be called by code anywhere in
the application.
Scenario
The methods in the class created in the previous lab are marked private by default
and so they cannot be accessed by other application elements. You have been
asked to allow the method to be accessed by other application elements

Challenge Yourself!
Change the modifier of each method to Public

Step by Step
1.
2.
3.
4.
5.

3-6

Open the AOT.


Find the class created in the previous lab.
Double click each method in the class.
Change the method modifier from Private to Public.
Save the changes.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes

Inheritance
Inheritance is a concept where one class can inherit all 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 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 be reused many times.

FIGURE 3.2 INHERITANCE IN OBJECT-ORIENTED PROGRAMMING

NOTE: In X++ one class can extend another class, and one extended data type
can extend another.

Extend a Class
To have a class extend another class, modify the classDeclaration code of the
child class by adding extends and then the parent class, shown as follows:
class Child extends Parent
{
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-7

Development II in Microsoft Dynamics AX 2012


Objects created from the Child

Have at least the same methods and variables as the Parent.

Can have methods and variables that do not exist in the Parent.

Can have methods from the Parent that are overridden or altered, in
the Child.

For example, if the Parent contains four methods:


Method1, Method2, Method3, Method4
the Child can have two of those methods overridden, plus an additional method.
Method1, Method3, Method5
If the code refers to one of the methods in the Child that has not been overridden,
the system will go to the Parent to retrieve the method. If that method then calls a
method that is in the Child, it will revert back to the Child.

Objects
Objects are created at run-time using the classes defined in the AOT. To create
an object from a class, the class has to be instantiated.

Instantiating a Class
Object instance methods can only be used when an object is instantiated from a
specific class. To instantiate a class, is to create a new instance of it. You can
have multiple instances of a class, meaning, you can have the same code running
multiple times. Think of how in Microsoft Word, you can have two documents
open at the same time. They are both running the same program, but are two
separate instances of that program.
When you create a new object, call the new() method to execute the code when
the object is instantiated.

3-8

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes


Once the class is instantiated, to execute a specific method from your code, use
the reference variable followed by a "dot" operator then the method name.
myClass

myClass;

;
myClass = new myClass();
myClass.myMethod();

The objective of following lab is to instantiate a class, and then execute a method
from that class.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-9

Development II in Microsoft Dynamics AX 2012

Lab 3.3 - Instantiating a Class


Scenario
You have been asked to execute the code written in the previous lab.

Challenge Yourself!
Create a job that instantiates the class written in the previous lab, and executes
the two methods you created.

Step by Step
1.
2.
3.
4.

Open the AOT.


Find the Jobs node.
Right-click select New Job.
Type the following code into the job.

PrintMyName

PrintMyName;

PrintMyName = new PrintMyName();


PrintMyName.setMyName();
PrintMyName.printMyName();
pause;

5. Press F5 to compile and run the job.

3-10

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes

Scoping and Parameters in X++


In X++ variables and methods are within a well-defined scope. A scope is the
area where an item is accessed.

Scopes in X++
Instance variables, declared in class declarations, can be accessed from any
methods in the class, and from methods in sub-classes that extend the class.
Local variables can be accessed only in the method in which they are defined.
public class ANewClass
{
int

abc;

}
private void aNewMethod()
{
int

xyz;

Variable abc is declared in the classDeclaration of ANewClass and variable xyz


is declared in aNewMethod. The variable xyz can only be used within the scope
of the method aNewMethod, but the variable abc can be accessed by all methods
in the class.

Methods with Parameters


All methods in X++ have their own scope. To use data from a different scope,
transfer the data into the new scope using parameters.
A method can have one or more parameters. Within the scope of the method
these parameters are treated like local variables, initialized with the value from
the parameter in the method-call.
private void methodWithParameters(str
= 1)

_parm1, int

_parm2

{
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-11

Development II in Microsoft Dynamics AX 2012


All parameters are passed by value, this means you cannot change the value of
the original variable, but only the local variable in the method, which is a copy of
the original.
In the previous example, the second parameter is assigned a default value. This
means that when the method is called, the second parameter is optional. If it is
called without a second parameter, _parm2 will be set to 1.
BEST PRACTICE: Method parameter names should always start with an
underscore (_). Method parameters should never be written to within the code,
only read from.

Methods Returning Data


When you right-click a class in the AOT and select New method, the method is
declared with the keyword Void. The void (empty) specifies that the method
does not return a value.
When enabling a method to return a value, remember two things:

Replace the void with an Extended Data Type to specify the type of
data to receive from the method. Any kind of data can be returned
including table buffers and class objects.

Write return followed by a specification of the data that you want to


receive for any manipulation of the data.

private description getStringValue()


{
description

myTxt = "Text";

return myTxt;
}

3-12

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes

Lab 3.4 - Use Method Parameters


Scenario
Isaac has been asked to write a method that accepts a parameter.

Challenge Yourself!
Modify your class to print your name, by allowing the method that sets the name
variable to accept a parameter and set the name variable from that parameter.
You will also need to modify the job so that you pass your name into the method
when you run it.

Step by Step
1.
2.
3.
4.
5.
6.
7.
8.

Open the AOT.


Find the class created earlier in this lesson that prints your name.
Double-click the method setMyName().
Modify the code so the method looks the same as shown in the
following example.
Press F8 to save and compile the code.
Find the job in the AOT that executes the class.
Modify the job so that the line that calls the setMyName() method is
called with your name.
Press F5 to save and run the job.

public void setMyName(str _myName)


{
}

myName = _myName;

static public void executePrintMyName(Args _args)


{
PrintMyName
PrintMyName;
PrintMyName = new PrintMyName();

PrintMyName.setMyName("Isaac");
PrintMyName.printMyName();
pause;

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-13

Development II in Microsoft Dynamics AX 2012

Referencing Object Methods


It is common to call methods within one class from other methods in that class.
To refer to a method in the same class, use the keyword this.

Example of Using This


A class has a method called myMethod() and another called run(). The run()
method calls the myMethod() method.
public void run()
{
this.myMethod();
}

3-14

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes

Lab 3.5 - Create a Run Method


Scenario
Isaac is required to create a method that calls other methods in the same class

Challenge Yourself!
Add a method named run to the class that prints your name. From this method
call the two methods that set and print the value. Modify the job that executes the
class to call the new run method.

Step by Step
1.
2.
3.
4.
5.
6.
7.
8.

Open the AOT.


Find the class created earlier in this lesson that prints your name.
Right-click the class and select New Method.
Modify the code so the method looks the same as shown in the
following example.
Press F8 to save and compile the code.
Find the job in the AOT that executes the class.
Modify the job to the code shown in the following example.
Press F5 to save and run the job.

public void run()


{

this.setMyName("Isaac");
this.printMyName();

static void executePrintMyName(Args _args)


{
PrintMyName
PrintMyName;
;
PrintMyName = new PrintMyName();
PrintMyName.run();
pause;
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-15

Development II in Microsoft Dynamics AX 2012

Method Types
There are many different types of methods. Some of the more common types are
discussed as follows.

Static Methods
Static methods are attached to a class. However, they do not need that class to be
instantiated to execute that method. They are not within the scope of the class, so
any class variables are not available in a static method.
Static methods are declared static by using the Static method modifier.
Static methods are called using the class name followed by two colons (::) and
then the methods name.
The following example shows a static method declaration, and a call to that static
method.
static public void myStaticMethod()
{
}

myClass::myStaticMethod()

Main Method
The main method is a static method that can be used to call a constuctor. It is
special because its name is required to be "main". It is used by the system when
the class is run directly from a menu item and it takes a parameter of type args.
Args is a class that is used to pass parameters between objects, for instance,
various parameters can be set on the properties on a menu item. When the menu
item calls a class, the args class containing those property values is passed to the
main method using the args parameter.

3-16

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes


Display Methods
Display methods are used on forms. They are commonly created on the table, and
can also be defined on the form. Display methods return a value that is displayed
on the form or report. They are often used to display a calculation, or to look up a
single field from another table. The following example shows how to display the
item name on a form that displays data from a table containing the item id.
// BP Deviation documented
display itemName itemName()
{
inventTable

inventTable

select name from inventTable


where inventTable.itemId == this.itemId;
return inventTable.name;
}

The first line in this code is a comment to the compiler indicating that a Best
Practice deviation is considered and evaluated as reasonable. The deviation is
because a display method is able to return any data from any table or field in the
system, and so the security implications should be considered.

Accessor Methods
Accessor methods enable other elements to set or get the values of variables in a
class and it is common that they do both.
The following example accepts a value as a parameter, sets a class variable to
this value and then returns the value. The parameter has a default value set to the
class variable value, so if the method is called without a parameter, it returns the
value of the class variable. If it is called with a value in the parameter, then the
class variable is set to this value.
public str myName(str

_myName = myName)

{
myName = _myName;

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-17

Development II in Microsoft Dynamics AX 2012


return myName;
}

Tables as Classes
A table can be considered an independent class used to address fields or methods
defined on that table. In fact when a table is instantiated, it is done so with the
system class called xRecord. This class contains methods called when
committing record changes to the database and some other system methods that
operate on records.
Differences between tables and classes include the following:

A place for a table buffer is automatically assigned in a table (in


classes the new method is used).

Fields in tables are public; they can be referred to from everywhere.

Fields in tables can be referred to directly; for example, in a report,


whereas variables in a method can only be referred to using accessor
methods.

Table Code
The following example illustrates how table code differs from code for a class.
str text;

text = CustTable.name;
print CustTable.name;
referred to directly

// Fields in a table are public


// Fields in a table can be

Eventing
The eventing feature lets the user use a publisher and subscriber model when
modifying Microsoft Dynamics AX. Events can be modeled in the AOT or be
used as a programming construct and can be handled in either X++ code or in
managed code.
NOTE: Modeled events are only available on classes and not tables or forms.

3-18

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes


Overview
The Microsoft Dynamics AX architecture includes application layers that can be
customized in upper layers. For example, when Microsoft ships a class in the
SYS layer, a developer can change the class in an upper layer such as the CUS
layer. At run time, the X++ language engine use the version of code in the
highest layer. You can use events to decouple the custom code from the
implementation of the underlying layer. The application developers from a lower
level can freely change the implementation at any time without the developers of
the upper layer having to make any changes to their code, as long as the modified
code author raises the same events in the same order. Basically, the application
developers build an API enabling customization through events.

Eventing Terminology
Microsoft Dynamics AX events are modeled after the .NET event concepts and
introduce the following new terminology:
Term

Definition

Producer

The producer is the logic that contains the code that causes a
change. This means that it is the entity that emits events.

Consumer

The consumer is the application code that manifested an


interest in being notified when a specific event occurs. This
means that it is an entity that receives events.

Event

An event is a representation of a change that happened in the


producer. Microsoft Dynamics AX 6.0 supports Pre and Post
events that occur before and after a method is called.

Event
Payload

The event payload is the information that the event carries


with it. If a person is hired, for example, the payload includes
the employee's name and date of birth, and so on.

Delegate

A delegate is the definition of the information passed from the


producer to the consumer when an event happens.

Event Handlers
Event handlers are methods that are called when the delegate is called, directly
through code (for the coded events) or from the environment (in the modeled
events). The relationship between the delegate and the handlers can be
maintained in code or in the AOT.
The X++ language now features the delegate keyword. When program conditions
meet the programmer's criteria for the event, the X++ code can call the delegate,
and that causes the delegate to call all the event handler methods that are added
to the delegate.
To create a delegate, right-click the class and select New->Delegate.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-19

Development II in Microsoft Dynamics AX 2012


Adding Handlers in the AOT
The user must identify a static method to handle the event on the delegate.
However, when adding event handlers from code, described in the following
material, instance methods are also applicable as event handlers. Event handlers
can be added to the delegate by dragging the event handler to the delegate node
that represents the event to be handled.

Adding Handlers in Code


Use special X++ syntax to remove or add event handlers to events. The delegate
name appears on the left side of the += operator. On the right side the keyword
event handler is given, together with the eventhandler keyword and the qualified
name of the handler to add. The compiler will ensure that the parameter profiles
of the delegate and the handler match.
private void AddStaticHandler()
{
;
this.MyDelegate += eventhandler
(Subscriber::MyHandler);
}

Pre and Post Events


You can subscribe an event handler to automatically run immediately before a
method is run. The event handler can change the parameter values before they are
entered into the method. You can also subscribe an event handler to run
immediately after a method is run. The event handler can change the value that is
returned by the method, before the return value is received by the caller of the
method.
Event handlers for these before and after events are visible in the AOT as sub
nodes on the methods to which they apply.

3-20

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes


Procedure: Adding a Post Event
Use the following procedure to add a post event to the method that is used to
determine whether or not the user may post a packing slip for the current sales
order.
1. In the AOT create a new class called SalesTableTypeDelegate.
2. Create a new method called mayPackingSlipBeUpdated and add
the following code
public static void mayPackingSlipBeUpdated(XppPrePostArgs
_args)
{
boolean ret;

ret = _args.getReturnValue();
_args.setReturnValue(ret && dayOfWk(systemDateGet()) ==
WeekDays::Monday);
}

3. Save your changes.


4. In the AOT locate the class SalesTableType.
5. Expand the class node and find the method
mayPackingSlipBeUpdated.
6. Right-click the method and select New Event Handler Subscription.
The EventHandler1 event handler node is created.
7. In the property sheet for EventHandler1, set the Name property to
mayPackingSlipBeUpdatedPost, set the CalledWhen property to
Post, set the Class property to SalesTableTypeDelegate, set the
Method property to mayPackingSlipBeUpdated.
8. Test your modification in the sales order form and observing that the
packing slip button is only available when the packing slip can be
posted and it is a Monday.
This is of course a modification that would not normally be required. However
this kind of modification may be used in for example, a workflow. If the sales
order needs to be approved before it can be packing slip posted, then this method
could validate that it has been approved. In this way you have added a new
validation without modifying the standard code.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-21

Development II in Microsoft Dynamics AX 2012

Lab 3.6 - Create a Calculator Class


Scenario
You have been asked to create a class than can do simple calculations on two
numbers.

Challenge Yourself!
Create a class that has two class variables that are set using accessor methods.
These variables are to hold 2 numbers. Add four methods that will add, subtract
multiply and divide these 2 numbers, and then return the calculated value. Write
a job to test your class.

Step by Step
1. Create a new class
2. Add the following methods and code to the class.
public class Calculator
{
real
value1;
real
value2;
}

3-22

private real parmValue1(real


{
value1 = _value1;
return value1;
}

_value1 = value1)

private real parmValue2(real


{
value2 = _value2;
return value2;
}

_value2 = value2)

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes


public real add()
{
return value1 + value2;
}

public real subtract()


{
return value1 - value2;
}

public real multiple()


{
return value1 * value2;
}

public real divide()


{
return value1 / value2;
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-23

Development II in Microsoft Dynamics AX 2012

Summary
This course introduced objects and classes within the Microsoft Dynamics AX
X++ development, including how to declare classes and instantiate objects.
Additionally, you worked with variables using simple and extended data types,
and used events to reduce the possibility of code merging during upgrades when
modifying code.

3-24

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes

Test Your Knowledge


Test your knowledge with the following questions.
1. Name two different types of methods that can be created in X++ and describe
their differences.

2. What is the reserved word in a function that is used when the method does
NOT return a value?

3. To execute a class's methods from a menu item, modify the __________


method.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-25

Development II in Microsoft Dynamics AX 2012

Quick Interaction: Lessons Learned


Take a moment and write down three key points you have learned from this
chapter
1.

2.

3.

3-26

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 3: Objects and Classes

Solutions
Test Your Knowledge
1. Name two different types of methods that can be created in X++ and describe
their differences.
MODEL ANSWER:
Object methods can only be activated by an object that has been instantiated
from the specific class. An object method is called as follows:
ref_name.testmethod();
Class methods can be attached directly to a class and do not need an
instantiated object to work. Use the 'static' modifier when you create class
methods. A class method is called as follows:
Class_name::testmethod();
2. What is the reserved word in a function that is used when the method does
NOT return a value?
MODEL ANSWER:
void
3. To execute a class's methods from a menu item, modify the __________
method.
MODEL ANSWER:
Main

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

3-27

Development II in Microsoft Dynamics AX 2012

3-28

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database

CHAPTER 4: ACCESSING THE DATABASE


Objectives
The objectives are:

Retrieve data from the database using a select statement.

Create, update and delete data in the database.

Use and build queries using kernel classes.

Introduction
This course will show how to develop modifications that interact with the
database. This functionality is used frequently so it is an important part of
learning how to develop using X++.

Scenario
Isaac, the Systems Developer, is writing a program that requires data to be read
from the database. Additionally the data must also be updated and written back to
the database. To do this, Isaac must use the select statement and queries so that
the data can be retrieved correctly and efficiently, while ensuring the data
maintains its integrity.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-1

Development II in Microsoft Dynamics AX 2012

Retrieving Data
Microsoft Dynamics AX 2012 accesses data using select statements and queries.
This section focuses on select statements.

Table Buffers
A table buffer stores complete records in a variable. A table buffer is declared
like a variable the table name is specified in the declaration. It is required when
you use select commands to retrieve records and is declared before the select
statement.
The following code shows a table buffer declaration:
CustTable
CustTable

custTable; //declares a table buffer for the

When a select statement result is assigned to a table buffer, the variable can be
considered a subset of data from that table depending on the criteria of the
search.

Select Statements
Select statements are used to retrieve data from a database. The pure select
statement returns records to a table buffer. The following example shows code
that selects a record from the Customer table where the customer account number
is 1103 and also prints the customer's address. Use the legal entity CEU.
CustTable

custTable;

select custTable
where custTable.AccountNum == "1103";
print "This is the credit limit of Customer " +
custTable.AccountNum + ": " + num2str(custTable.CreditMax,1,-1,-1,-1);
pause;

4-2

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database


Select Statement Definition
The following code shows a select statement and its components:
select <Find Options>
<TableBuffer or {FieldList from [TableBuffer]}>
<Aggregate (field identifier)>
<Sorting Options field identifier[Direction]>
<Index clause (index)>
where <selection criteria>
<Join Clause join>

Select Statement Keywords


The following table contains keywords used in select statements and their
descriptions:
Syntax
Category

Keyword

Description

Find Options

reverse

Returns records in reverse order.

firstFast

Speeds up the fetch. This is a priority hint


that means the first row appears quicker but
the total return time may be slower. A
typical use of this option is dialog updates.

firstOnly

Speeds up the fetch. This tells Microsoft


Dynamics AX to fetch only the first record.

forUpdate

Selects records exclusively for update. The


operation performed on the fetched records
is update. The records will be locked so
other users cannot update these records.

noFetch

Indicates that no records are fetched. This is


used when the result of the select is passed
to another application object; for example, a
query that performs the fetch.

sum

Returns the sum of the fields from the rows


given by the group by clause. Can be used to
sum all accounts, order lines, and so on.

avg

Returns the average of the fields from the


rows given by the group by clause.

minof

Returns the minimum of the fields from the


rows given by the group by clause.

Aggregate

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-3

Development II in Microsoft Dynamics AX 2012


Syntax
Category

Sorting
Options

Direction

Index Clause

Join Clause

Keyword

Description

maxof

Returns the maximum of the fields from the


rows given by the group by clause.

count

Returns the number of fields from the rows


given by the group by clause.

order by

Instructs the database to sort selected


records by fields in the order by list.

group by

Instructs the database to group selected


records by fields in the order by list.

asc

Sorts the order by or group by clause in


ascending order.

desc

Sorts the order by or group by clause in


descending order.

index

Sorts the selected records as defined by the


index.

index hint

Gives the database a hint to use this index to


sort the selected records as defined by the
index. The database might ignore the hint.

exists

Returns a record only if the linked record


exists.

notexists

Returns a record only if the linked record


does not exists.

outer

Returns all records regardless of whether


linked records exist.

Examples Using Keywords


The following code shows examples of select statements. The comments describe
their use.
CustTable
custTable;
the CustTable

// Declares a table buffer for

// Returns only the first record from the custtable.


select firstOnly custTable;

// Returns a count of the number of customer account


numbers in the
// table and prints the result to screen.

4-4

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database


select count(AccountNum) from custTable;
print custTable.AccountNum;
pause;

Field Lists
To perform a lookup on specific fields in a table, use a field list in the select
statement. For example, to return only the name of a customer whose account
number is '4000' use a field select statement.
CustTable

custTable;

select name from CustTable


where CustTable.AccountNum =="4000";

Using a field list is a good practice because it can increase performance.

Using While Select


The while select statement loops through many records fulfilling specific criteria
in a table. Use this loop to perform statements on each record. The following
code shows an example of a while select statement. This code loops through the
customer table and prints the account number, name, and address of each record
in the table.
CustTable custTable;
while select accountNum, currency, creditMax from custTable
{
print custTable.AccountNum, " ", custTable.currency, "
", custTable.creditMax;
pause;
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-5

Development II in Microsoft Dynamics AX 2012


Using Ranges in Select Statements
A range can be set for records being selected. This range is specified in the
where clause of the select statement using relational operators. The following
example selects customers who have account numbers greater than 4005 and less
than 4017.
CustTable custTable;

while select custTable


where custTable.AccountNum > "4005"
&& custTable.AccountNum < "4017"
{
print custTable.AccountNum , " ",custTable.currency;
}
pause;

Sorting Options
You can sort data retrieved from the database in many ways. This includes:

Using existing indexes on the tables.

Using the order by clause in a select statement.

Using the group by clause in a select statement.

To use an index on a select statement, use the keyword index followed by the
name of the index:
CustTable custTable;

while select custTable index AccountIdx


{
print custTable.AccountNum, " ", custTable.currency;
}
pause;

4-6

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database


The result of this search is in the order specified by the index. You can view
available indexes for a given table in the Application Object Tree (AOT).
Indexes should only be specified when the sequence of records is important and
that sequence matches the index exactly.

Order By
If an index does not exist on a table, you can create a temporary index using an
order by clause in the select statement. This lets you specify one or more table
fields to sort the result. By default, records are sorted in ascending order. To sort
in descending order, use the keyword desc after the order by field. The following
example shows how to use the order by clause in descending order.
CustTable custTable;

while select custTable order by AccountNum desc


{
print custTable.AccountNum, " ", custTable.currency;
}
pause;

Group By
Use the group by clause to group selected records by field. The following
example shows how to display the number of sales orders by customer group
from the Sales table.
SalesTable salesTable;

while select count(recId) from salesTable group by


CustGroup
{
print salesTable.CustGroup,"
",int642Str(salesTable.RecId);
}
pause;

The output would be a list of customer groups with the total number of sales
orders that exist for customers in that group. The count() function counts the total
number of records and places the result in the field specified in the brackets.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-7

Development II in Microsoft Dynamics AX 2012


Joins
Use joins to link tables so they can return values together. By default, inner joins
are created. The following table describes the types of joins available:
Join Type

Use to

inner

Combine records into one table only when there are


matching values in a common field.

outer

Combine records into one table even if there are no matching


values in the common field.

exists

Combine records from one table whenever a value exists in a


common field in another table.

notexists

Combine records from one table whenever a value in a


common field in another table does not exist.

Not only is there additional syntax needed to specify what table is being joined,
but the where clause also has to be modified. Within the where clause, the two
fields that relate the tables must be specified in addition to any other conditions
of the search. When using an inner or outer join the table buffers of both tables
are populated with the retrieved records. An exists or not exists join only
populates the first table.

Example: Using a Join


The join shown in the following code combines records from the Customer table
and the Customer transaction table to show all vouchers and dates for customer
4000.
CustTable

custTable;

CustTrans

custTrans;

while select AccountNum from custTable


join custTrans
where (custTrans.AccountNum ==
custTrans.AccountNum)
&& custTrans.AccountNum =="1103"
{

4-8

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database


print custTable.accountNum, " ",custTrans.Voucher,' ',
date2str(custTrans.TransDate,213,1,4,2,4,2);
}
pause;

Cross-company Support
Microsoft Dynamics AX can have multiple companies in one data base. It is a
common requirement to retrieve data from many or all of these companies in a
function. This can be achieved in one select statement by using the
crossCompany keyword. If just the keyword is used, it will search all companies.
You can also specify a container that defines which companies to search.
container
custTable

conCompanies = [ 'cee', 'ceu' ];


custTable;

while select crossCompany : conCompanies custTable


{
print custTable.accountNum;
}
pause;

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-9

Development II in Microsoft Dynamics AX 2012

Lab 4.1 - Retrieving Data


Scenario
Isaac has been asked to produce a list of customer account numbers and names
sorted by name.

Challenge Yourself!
Create a job that will retrieve all customer accounts and print the account number
and name. The list should be sorted by name. Note that the customer name is not
stored in the customer table; it is stored in the DirPartyTable, which is related to
the customer table through the CustTable.Party field and the
DirPartyTable.RecId field.

Step by Step
1. Open the AOT.
2. Create a new job
3. Add the following code.
CustTable

CustTable;

DirPartyTable DirPartyTable;
while select DirPartyTable order Name
join CustTable
{

where custTable.Party == dirPartyTable.RecId


info(DirPartyTable.Name+', '+CustTable.AccountNum);

4-10

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database

Data Manipulation
Data manipulation in X++ refers to interactively using SQL commands. These
commands include insert, update and delete. These are required to modify the
data in the database. When values are assigned to a table buffer, the data is not
updated in the database.

Insert
To create new records in the database, use the insert() method on the table. The
data is first set on the table buffer by assigning values to fields. The data is then
committed to the database by calling the insert() method.
custTable

custTable;

custTable.accountNum = "1234";
custTable.Currency = "USD";
custTable.insert();

Insert_Recordset
Insert_Recordset copies data from one or more tables in one call to the database.
This is much faster than selecting records individually and then inserting the new
records in to the table.
In the following example, Isaac has been asked to copy all Employee records to
the vendor table for the purposes of being able to pay expenses to the employee.
Only specific information, such as name and address needs to be copied.
VendTable vendTable;
HcmWorker hcmWorker;
Insert_RecordSet VendTable (accountnum, Party)
select PersonnelNumber, person from HcmWorker;

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-11

Development II in Microsoft Dynamics AX 2012


Update
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 select forUpdate 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.
The following example updates the customer name on all sales orders for the
customer with the account number 2001
SalesTable salesTable;

ttsbegin;
while select forupdate salesTable
where salesTable.CustAccount =="2001"
{
salesTable.SalesName ="New Enterprises";
salesTable.update();
}
ttscommit;

NOTE: The use of ttsbegin and ttscommit. This indicates the start and end of a
transaction. This topic will be discussed at the end of this section.

4-12

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database


Update_Recordset
The update_recordset command allows the manipulation of many records in one
operation. This command speeds up database processing because of fewer calls
to the database. Review the update function using the update_recordset
command.
SalesTable salesTable;

update_recordset salesTable
setting salesName ="New Enterprises"
where salesTable.custAccount =="2001";

NOTE: You do not have to use the ttsbegin; or ttscommit; when you use the
update_recordset command, however it is recommended to consider using a
transaction when making other updates to the database at the same time.

Delete
The delete command deletes a complete record from the database that meets the
condition of the select statement. The syntax of the delete command resembles
update and insert. This example deletes a row in the database with a customer
account of '2032'.
CustTable custTable;

ttsbegin;
Select forUpdate custTable
where custTable.accountnum =="2032";
custTable.delete();
ttscommit;

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-13

Development II in Microsoft Dynamics AX 2012


Delete_from
The delete_from command removes multiple records from the database at one
time. Similar to the update_recordset command, delete_from consolidates
many database calls into one operation, and increases database performance.
CustTable custTable;

delete_from custTable
where custTable.Currency == "ABC";

Transaction Integrity Checking


It is important to ensure the integrity of all transactions within the system. When
a transaction begins, 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. Use the Transaction Tracking
System (tts) to help you ensure database integrity.
The following keywords help in integrity checking:

ttsbegin: Indicates the beginning of the transaction.

ttscommit: Indicates the successful end of a transaction. This


ensures the transaction performed as intended upon completion.

ttsabort: Used as an exception to abort and roll back a transaction to


the state before the ttsbegin.

Nested ttsbegins and ttscommits are ignored in that a lock is held until the last
ttscommit is reached. However the system does keep track of the tts level. Each
time a ttsbegin is called, the tts level increases by one. Every ttscommit decreases
the level by one.

4-14

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database

Lab 4.2 - Update


Scenario
The item table needs to be updated so that all items in the item group
"Television" have a purchase tolerance of 2 percent. Isaac has been asked to
write a job that will achieve this.

Challenge Yourself!
Write a job that will find all items in the Television item group, and set the price
tolerance group to 2 percent.

Step by Step
1. Open the AOT.
2. Create a new job.
3. Add the following code.

InventTable InventTable;
InventItemGroupItem inventItemGroupItem;
ttsbegin;
while select forupdate InventTable
exists join inventItemGroupItem
where inventItemGroupItem.ItemId == InventTable.ItemId
&& inventItemGroupItem.ItemGroupId == 'Television'
{
InventTable.ItemPriceToleranceGroupId ="2%";
InventTable.update();
}
ttscommit;
InventTable InventTable;
InventItemGroupItem inventItemGroupItem;
ttsbegin;
while select forupdate InventTable

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-15

Development II in Microsoft Dynamics AX 2012


exists join inventItemGroupItem
where inventItemGroupItem.ItemId == InventTable.ItemId
&& inventItemGroupItem.ItemGroupId == 'Television'
{
InventTable.ItemPriceToleranceGroupId ="2%";
InventTable.update();
}
ttscommit;
InventTable InventTable;
InventItemGroupItem inventItemGroupItem;
ttsbegin;
while select forupdate InventTable
exists join inventItemGroupItem
where inventItemGroupItem.ItemId == InventTable.ItemId
&& inventItemGroupItem.ItemGroupId == 'Television'
{
InventTable.ItemPriceToleranceGroupId ="2%";
InventTable.update();
}
ttscommit;

4-16

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database

Queries
A query is an application object in the AOT. A query performs the same function
as the select statements. It is a better option because it allows for more flexible
user interaction when defining which records are to be retrieved. Queries provide
more flexibility, especially when sorting and specifying ranges.
The following figure shows an expanded query in the AOT:

FIGURE 4.1 EXPANDED QUERY IN THE AOT

With this example, the CustTable query has three data sources, two of which
have defined sorting and ranges. This section discusses methods within queries
and how to construct a simple query using X++.

Executing a Query in X++


Queries can also be created and manipulated using X++. There are a number of
classes available that you can use to achieve this.
Two important classes when executing a query are:

Query()

QueryRun()

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-17

Development II in Microsoft Dynamics AX 2012


The Query() class does not "fetch" records, this is accomplished by using the
QueryRun() class. The Query() class provides the framework for the query
whereas the QueryRun() class starts this framework dynamically. The following
example creates and runs a simple query. The QueryStr() function validates that
the element of type Query called Cust exists in the AOT.
Query

query = new Query (QueryStr(Cust));

// Use the query to build a queryRun object


QueryRun queryRun = new QueryRun (query);
// Traverse some records...
while (queryRun.next())
{
// ...
}

Building a Query in X++


Queries contain many important elements. These elements have been discussed
in earlier courses in the context of the AOT. This section discusses these
elements from within the context of X++. Elements include datasources, ranges,
and sort fields which build upon each other.
There are two more classes to note before building a query:

QueryBuildDataSource

QueryBuildRange

QueryBuildDataSource
Data sources are what queries are built upon. They are arranged in a hierarchy
and define the sequence in which records are fetched from tables assigned to the
data source. The following example adds a data source to a query using X++:
Query

query = new Query();

QueryBuildDataSource
qbds =
query.addDataSource(TableNum(SalesTable));

Notice that the data source is an object, but the query object, 'query', requires a
method to add this data source to the query and assign the SalesTable to the data
source.

4-18

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database


QueryBuildRange
A QueryBuildRange object is embedded within a data source of a query and
defines which records should be selected from the data source. A querybuild
range is built upon a QueryBuildDataSource object. The following example
uses the QueryBuildRange:
Query

query = new Query();

QueryBuildDataSource qbds =
query.addDataSource(TableNum(SalesTable));
QueryBuildRange qbr =
qbds.addRange(FieldNum(SalesTable,CustAccount));

Example: Building a Query in X++


The following code demonstrates how a query is built from scratch in X++. This
query returns all sales orders, from the SalesTable, for customer '4008', sorted by
the SalesId.
Query
QueryRun
QueryBuildDataSource
QueryBuildRange
SalesTable

query;
queryRun;
qbds;
qbr;
SalesTable;

query = new Query();


//this line attaches a table to the qbds data source object
qbds = query.addDataSource(TableNum (SalesTable));
//this line attaches a range to the 'SalesTable' //data
source, the range is the CustAccount
qbr = qbds.addRange(FieldNum (SalesTable,CustAccount));
// The range is set to '2001'
qbr.value ('2001');
// The query will sort by sales id
qbds.addSortField (FieldNum(SalesTable,SalesId));
// The queryRun object is instantiated using the query
queryRun = new QueryRun(query);
// The queryRun object loops through all records returned
while (queryRun.next())
{

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-19

Development II in Microsoft Dynamics AX 2012


// The current record is assigned to the salesTable
variable
SalesTable = queryRun.get(tableNum(SalesTable));
}

print SalesTable.SalesId;

pause;

4-20

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database

Lab 4.3 - Create a Query Using X++


Scenario
Isaac has been asked to provide a list of vendors of packaging materials.

Challenge Yourself!
Write a job that will produce a list of vendors. The job should build a query using
X++, and the query should have a range that limits the list to vendors in vendor
group "50", and sort by account number.
Add code that will allow the user to modify the query ranges at run time.

Step by Step
1.
2.
3.
4.

Open the AOT.


Create a new job.
Add the following code.
Press F5 to save and run the code.

Query
QueryRun
QueryBuildDataSource
QueryBuildRange
vendTable

query;
queryRun;
qbds;
qbr;
vendTable;

query = new Query();


qbds = query.addDataSource(TableNum(VendTable));
qbr = qbds.addRange(FieldNum(VendTable,VendGroup));
qbr.value('50');
qbds.addSortField(FieldNum(VendTable,AccountNum));
queryRun = new QueryRun(query);
if (queryRun.prompt())
{
while (queryRun.next())
{
VendTable = queryRun.get(tableNum(VendTable));
info(VendTable.Name());
}
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-21

Development II in Microsoft Dynamics AX 2012

Summary
This course showed how to search for data using the select command and how to
create criteria to specify which records will be selected. This course also showed
how these records can be updated or deleted and how to insert new records.
Additionally, this course showed how to build a more user-friendly search using
queries to specify the search criteria.

4-22

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database

Test Your Knowledge


Test your knowledge with the following questions.
1. What is wrong with the following line of code? Rewrite it so that it compiles
correctly: select count(vendTable.AccountNum);
2.

3. What are three ways to sort data on a select statement?

4. What are the three keywords associated with the Transaction Tracking
System and what is their significance?

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-23

Development II in Microsoft Dynamics AX 2012

Quick Interaction: Lessons Learned


Take a moment and write down three key points you have learned from this
chapter
1.

2.

3.

4-24

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 4: Accessing the Database

Solutions
Test Your Knowledge
1. What is wrong with the following line of code? Rewrite it so that it compiles
correctly: select count(vendTable.AccountNum);
2.
MODEL ANSWER:
You are only supposed to specify a field name as a parameter to the keyword
COUNT and then add a from clause after this function. The following shows
the code written correctly:
Select COUNT(accountnum) from vt;
3. What are three ways to sort data on a select statement?
MODEL ANSWER:
a. Using existing indexes on the tables
b. The order by clause in a select statement that will return records in
ascending order by default and if specified, can return them in descending
order.
c. The group by clause in a select statement will group records by a selected
field.
4. What are the three keywords associated with the Transaction Tracking
System and what is their significance?
MODEL ANSWER:
ttsBegin: You mark the beginning of the transaction with ttsbegin.
ttsCommit: You mark the successful end of a transaction with a ttscommit.
This ensures the transaction is performed the way it is supposed to upon
completion.
ttsAbort: This can be used as an exception to make a transaction be aborted
and rolled back to its state before the ttsbegin. You insert a ttsAbort wherever
you want this to occur.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

4-25

Development II in Microsoft Dynamics AX 2012

4-26

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 5: Exception Handling

CHAPTER 5: EXCEPTION HANDLING


Objectives
The objectives are:

Examine the exception handling mechanism in


Microsoft Dynamics AX.

Use the Try, Catch, and Retry statements.

Throw an exception from code.

Identify and create code used to handle optimistic concurrency


exceptions.

Introduction
When code is running, exceptions can occur because of user input, setup, data,
code, or installation problems. Users need a clear indication of when exceptions
occur so that they can resolve the problem or report it to an administrator or
systems developer, who can investigate what went wrong.
Therefore, a good programming practice involves handling exceptions
throughout the program, and consistently reporting. When an exception occurs, it
is known as an exception being thrown. The ability of the program to know that
an exception has occurred and to react to it is known as catching the exception.
Within Microsoft Dynamics AX2012, X++ has a built-in mechanism to help with
exception handling. This feature allows developers to catch exceptions during
program execution and control how the program reacts to the exception.

Scenario
Isaac, the Systems Developer, needs to improve his code so that any errors that
occur during the execution of the program, whether because of user input, data,
his own code, or any other reason, are reported to the user, and that actions can
occur to correct the error.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

5-1

Development II in Microsoft Dynamics AX 2012

Exceptions
An exception is a situation where the flow of a program's execution is
interrupted. Examples of exceptions include the following:

Printing to a printer that is not powered on

Accessing a file that does not exist

Updating a record that does not exist

When these exceptions occur, the program must handle them. For example, if the
user requests a file that does not exist, the program might have to catch the
exception and create a new file.
There are many types of exception thrown, depending on what caused the
exception. A majority of exception types are determined by the kernel and are not
usually thrown by application code. However, all exception types can be caught,
and it is the developer's responsibility to decide which exceptions must be
handled. The exception type is identified using the system enum Exception.
Because it is a system enum, it cannot be modified. Therefore, users cannot add
new exception types.

5-2

Exception

Description

info

Thrown when a message has been sent to the


Infolog. Do not throw an info exception manually.

warning

Thrown when something illegal, although nonfatal,


has occurred.

deadlock

Thrown when there is a database deadlock because


several transactions are waiting for one another.

error

Thrown when a fatal problem has occurred and the


transaction has stopped.

internal

Thrown when Microsoft Dynamics AX encounters


internal development problems at runtime.

break

Thrown when the user presses Break or Ctrl+C


during runtime.

DDEerror

Thrown when a problem occurs in the Dynamic


Data Exchange (DDE) system class.

sequence

For internal use only.

numeric

Thrown when a problem occurs during the use of


any numerical function.

CLRError

Thrown when a problem occurs during the use of


the Common Language Runtime (CLR)
functionality.

CodeAccessSecurity

Thrown when a problem occurs during the use of


CodeAccessPermission.demand.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 5: Exception Handling


Exception

Description

UpdateConflict

Thrown when a record being updated within a


transaction that is using Optimistic Concurrency
Control, and the recVersion value of the record
buffer and the database record are not equal. The
transaction can be retried (use a retry statement in
the catch block).

UpdateConflict
NotRecovered

Thrown when a transaction using Optimistic


Concurrency Control cannot be completed, and the
code will not be retried.

Try and Catch Statements


Try statements signify 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 in the associated Catch statements.
Catch statements come after the Try statement 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. It is also possible to define a Catch statement that is executed
for any exception type. Try statements can be made within the scope of other Try
statements. If a Catch statement is not defined for the exception being thrown by
an inner Try statement, the code will step out to the next outer Try statement to
attempt to find a matching Catch statement for the exception. This will continue
until a Catch statement is found, or there are no more outer Try statements.
Retry statements tell the system to go back to the Try statement and attempt to
execute the code again. Any data that is loaded before the Try statement will
remain as it is, but any data retrieved or modified after the Try statement will be
refreshed.
The following example has a Try statement, signifying the start of the exception
handling block of code. The code then tries to insert a new customer record.
CustTable
custTable;
Counter
retryCount;
#define.RetryMax(5)
try
{

custTable.AccountNum = "0001";
custTable.CustGroup = "50";
custTable.insert();

}
catch (Exception::Error)
{
error("There was an error while inserting the
record.");
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

5-3

Development II in Microsoft Dynamics AX 2012


catch (Exception::Deadlock)
{
if(retryCount < #retryMax)
{
retry;
}
}

There are then two catch statements. The first catches an error exception. The
error may be caused, for example, during the insert() method. The second catch
statement catches a deadlock exception. The database throws this exception when
it recognizes that a deadlock has occurred.
When a deadlock exception is thrown, all locks on tables that this process holds
are released. This could allow the other process or processes that are also
deadlocked to continue. By calling a retry, the process can attempt to update the
record again and may now be able to be completed. It is 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.

Throwing Exceptions
A Throw statement is used to throw an error that can be caught by a Catch
statement. The Throw statement explicitly declares what type of exception is
thrown to the Catch list. If the Try statement does not include a Catch list, the
exception moves to the next Try statement.
In the following example, the code throws an error exception and at the same
time, an error message is placed in the Infolog (this is a feature of the error
function in X++). When the error exception is caught, a second error message is
placed in the Infolog. Both error messages are then reported to the user.
CustTable custTable;
try
{

select custTable
where custTable.accountNum == "1019";
if (!custTable.RecId)
throw error("Customer does not exist");

}
catch (exception::error)
{
error ("Process was aborted");
}

5-4

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 5: Exception Handling


The previous lesson discussed the transaction tracking system and the ttsabort
statement. This statement ends the transaction and returns the data to its state at
the corresponding ttsbegin statement. When the system throws an exception,
ttsabort is called automatically, and so does not have to be called in a Catch
statement. Using the throw and error statements together in the previously
mentioned format, you effectively abort a transaction, jump to the Catch list to
handle the error exception, and send an error message to the user in one line.

FIGURE 5.1 THROWN ERROR MESSAGE

Demonstration: Debugging a Try, Catch Statement|


1.
2.
3.
4.
5.
6.
7.

In the AOT, create a new Job.


Copy the following code to the new Job.
Place a breakpoint on the Try statement.
Press F5 to compile and run the code. The debugger starts.
Press F10 to step over each line of code.
When the validateWrite() method fails, it throws an error exception.
The debugger then jumps to the Catch list, and the rest of the code in
the Try statement is not executed.
8. Step through the code to the end.
9. Note the error messages that are shown in the Infolog. The last two
messages were in the code in the job. However, the first three were
added during the validateWrite method.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

5-5

Development II in Microsoft Dynamics AX 2012


CustTable
try
{

custTable;

custTable.AccountNum = "0002";
custTable.CustGroup = "20";
if (!custTable.validateWrite())
{
throw error("Record failed validation");
}
custTable.insert();

info("Record was inserted in database");


}
catch (Exception::error)
{
error("There was an error inserting the record.");
}

Optimistic Concurrency Exceptions


The optimistic concurrency check (OCC) is a performance enhancing function
within Microsoft Dynamics AX. It presumes that any record retrieved from the
database is not updated, until it is actually proven to be updated by the database.
This means that fewer locks have to be placed on records in the database. This
allows for faster access for other users.
This also means that one user can update a record after another user has retrieved
it from the database. This can cause data inconsistency. If the second user then
also tries to update the record, an UpdateConflict exception is thrown. The
system does this by comparing the recVersion field on the record buffer at
runtime and the actual record in the database. The recVersion field value is
changed every time that an update is successfully made to a record.
The following code is an example of how to handle the UpdateConflict exception
that might be thrown.
try
{

...
}
catch (Exception::UpdateConflict)
{
//the TTS level is automatically reduced by 1
if (appl.ttsLevel() == 0)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::UpdateConflictNotRecovered;
}
else

5-6

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 5: Exception Handling


{
}

retry;

}
else
{
throw Exception::UpdateConflict;
//thrown to the caller
}
}

If a conflict due to OCC occurs, the system throws the UpdateConflict exception
and it is caught by the catch statement.
The code checks the current TTS level. If it is not zero, in other words, it is still
in a TTS transaction, it throws another UpdateConflict exception to the next
Catch list of the next outer Try statement in scope. This continues until it is no
longer inside a TTS transaction. The developer must make sure that when the
code is retried, all data is refreshed.
As soon as the code is outside all transaction scope, the retry statement is called.
The Try statement is then re-executed. If the problem continues for as many
retries as is specified in the #RetryNum macro (system default is 5), then the
UpdateConflictNotRecovered exception is thrown. This means the whole
transaction is aborted and stops retrying.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

5-7

Development II in Microsoft Dynamics AX 2012

Lab 5.1 - Handle an Exception


In this lab, you will use the exception handling features that are available in X++.
Scenario
The Accounts Receivable Department has asked for a basic form that will create
a new customer. They have requested that the user is prompted for the account
number, name and all mandatory fields. If the user does not enter all the required
data, the system must report which fields are missing, show a message that states
"Please enter all required fields," and not commit any data to the database. If any
error occurs the system will display a message that states "An error occurred.
Please try again."

Challenge Yourself!
Create a new class that will prompt the user for a new customer account number,
the name and all fields that are mandatory for the customer records. Use existing
methods to validate the record before inserting the record into the database. In the
case that not all data was entered, throw an error exception that has the error
message: "Please enter all required fields." The code to create the record must be
inside a try/catch statement. This must include a catch for the error exception
type and display the message: "An error occurred. Please try again.".

Need a Little Help?


Use the Dialog and DialogField objects to build a dialog with the user.
Wrap the insert logic in a Try statement and add a Catch statement for Exception
type Error.
Create a Main method on the class, which creates an object of its own class, and
calls the method to run the dialog and insert code.

Step by Step
1. Create a new class.
2. Copy the following methods by copying the classDeclaration to the
classDeclaration, and creating the main and run methods.
3. Compile the code.
4. Test the code by right-clicking the class and selecting open.

5-8

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 5: Exception Handling


class CustCreateCustomer
{
}
void run()
{
Dialog
customer");
DialogField
DialogField
DialogField
CustTable

dlg = new Dialog("Create new


dlgCust;
dlgGrp;
dlgCur;
custTable;

dlgCust = dlg.addField(extendedTypeStr(CustVendAc),
"Customer account");
dlgGrp = dlg.addField(extendedTypeStr(CustGroupId));
dlgCur = dlg.addField(extendedTypeStr(CurrencyCode));
if (dlg.run())
{
try
{
custTable.AccountNum
custTable.CustGroup
custTable.Currency

fields.");

= dlgCust.value();
= dlgGrp.value();
= dlgCur.value();

if (!custTable.validateWrite())
{
throw error("Please enter all required
}
else
{
custTable.insert();
}

}
catch (Exception::Error)
{
error("An error occurred. Please try again");
}

static void main(Args


{
CustCreateCustomer
CustCreateCustomer();
;

_args)
custCreateCustomer = new

custCreateCustomer.run();
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

5-9

Development II in Microsoft Dynamics AX 2012

Summary
This course described how Exception Handling is controlled in Microsoft
Dynamics AX. This course discussed the exception handling framework and
what steps are necessary to communicate exceptions to the end-users. Labs and
demonstrations throughout provided an opportunity to practice using try and
catch statements, the main tools that are used to handle exceptions.

5-10

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 5: Exception Handling

Test Your Knowledge


Answer the following questions related to Exception Handling. Check answers to
review questions in Appendix A.
1. What is the main idea behind exception handling in X++ programming?

2. What is the purpose of the try statement in a try...catch statement?

3. What is the function of a retry statement and when is it most useful?

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

5-11

Development II in Microsoft Dynamics AX 2012


4. How is the throw statement related to the Transaction Tracking System (tts)?

5-12

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 5: Exception Handling

Quick Interaction: Lessons Learned


Take a moment and write down three key points you have learned from this
chapter
1.

2.

3.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

5-13

Development II in Microsoft Dynamics AX 2012

Solutions
Test Your Knowledge
1. What is the main idea behind exception handling in X++ programming?
MODEL ANSWER:
The main idea behind exception handling is to plan for potential pitfalls
within the program. These exceptions are inevitable and if the code can
expect some of these issues and have contingency plans for the code, the
flow of the program is more efficient.
2. What is the purpose of the try statement in a try...catch statement?
MODEL ANSWER:
The try statement defines a block of code that is included in the try...catch
statement. It is used as the point to which the logical program flow will
return should it encounter a retry command.
3. What is the function of a retry statement and when is it most useful?
MODEL ANSWER:
The retry statement is used to make the try statement execute one more time.
This statement is used more for simple locks that can be released while in the
catch statement. This enables the try statement to execute without an
exception the next time through. It is most beneficial for overcoming
database locks.
4. How is the throw statement related to the Transaction Tracking System (tts)?
MODEL ANSWER:
The throw statement automatically initiates a ttsAbort statement every time
that it is called. The throw statement will force the current transaction to roll
back to its original state before the ttsBegin statement.

5-14

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 6: Security for Developers

CHAPTER 6: SECURITY FOR DEVELOPERS


Objectives
The objectives are:

Set permissions on application elements.

Design and create security policies.

Secure unsafe Application Programming Interfaces (APIs) using the


Code Access Security framework.

Authenticate data returned from display methods.

Introduction
This chapter introduces some more advanced security features of Microsoft
Dynamics AX.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

6-1

Development II in Microsoft Dynamics AX 2012

Permissions
The Development I in Microsoft Dynamics AX 2012 training course discussed
roles duties and privileges. These security levels cover access to single elements,
for example forms, and groups of elements needed to perform a duty. A
developer is responsible for defining more granular security levels by setting
access on tables and controls in a form, or by associating classes that perform an
action with a permission.

Form Permissions
Each form in the Application Object Tree (AOT) has a permissions node that
contains either four or five sub-nodes - Read, Update, Create, Delete and Correct.
Correct is only displayed if a table in the form has Date Effective data. Under
these nodes are four additional nodes - Controls, Tables, Server Methods and
Associated Forms.
When a table is added to a form data source, the table is automatically added to
the Tables node for each of the Permissions sub-nodes. Each of the nodes under
the Tables node has an EffectiveAccess property which sets what access is
allowed to the table
The EffectiveAccess property is automatically set based on properties on the data
source. If the data source property AllowDelete is set to No, the EffectiveAccess
property is set to Update. If the data source property AllowEdit is set to No, the
EffectiveAcces property is set to Read.

FIGURE 6.1 EFFECTIVE ACCESS IN THE VENDOR INVOICE JOURNAL


FORM

To set access for a control in the form, set the Securable property on the control
to Yes. The control can then be added to the Controls node under each of the
permissions nodes.

6-2

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 6: Security for Developers


Code Permissions
Code permissions are a set of custom permissions that are created manually in
the AOT under Security > Code Permissions. Menu items, especially Action
menu items, can use these by setting the LinkedPermissionType property to
CodePermission and the LinkedPermissionObject to the name of the code
permission. Service operations can also use code permissions by setting the Code
Permission property under the Service operation > Operation method >
Permissions > Associated Code Permissions node.

FIGURE 6.2 ACCESS TO POST A FREE TEXT INVOICE

Security Policies
Security policies use Extensible Data Security (XDS).

Definitions
The following definitions are used in conjunction with XDS.
Constrained table: This table or tables hold the data filtered based on the policy.
Primary table: This table is used to determine how data is filtered. For example,
for a filter based on an employee, the primary table would be the HcmWorker
table.
Policy query: This query is used to return data from the primary table that is then
used to filter the data in the constrained table.
Context: This controls the circumstances under which the policy is applied.
There are two types of context:

Role contexts means the policy is applied if the user is assigned to


the role.

Application contexts means the policy is applied based on


information set by the application.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

6-3

Development II in Microsoft Dynamics AX 2012


Scenario: Developing an XDS Policy
This procedure will show how to create a security policy that limiting users from
viewing other users prospects. In some sales environments, sales people closely
guard their prospect information, and they do not want other sales people to view
their prospects data.
A prospect is stored in the smmBusRelTable. The employee who is responsible
for the prospect is stored in the MainContactWorker field. An employee is
connected to the current user through the DirPerson and DirPersonUser tables.
There are two stages in creating the XDS policy - create the policy query and
create the security policy.

Procedure: Creating a Policy Query


The steps to create the policy query are as follows:
1. In the AOT, create a new query, rename it to HcmWorkerUser.
2. From a second AOT, locate the table Data Dictionary > Tables >
HcmWorker.
3. Drag the table HcmWorker to the Data Souces node of the query.
4. In the property sheet of the Fields.node of the HcmWorker_1 data
source, set the Dynamic property to Yes.
5. From the second AOT, locate the table Data Dictionary > Tables >
DirPerson.
6. Drag the table DirPerson to the Data Sources node of the
HcmWorker_1 data source.
7. In the property sheet for the DirPerson_1 data source, set the
Relations property to Yes.
8. In the property sheet for the Fields node of the DirPerson_1 data
source, set the Dynamic property to Yes.
9. From the second AOT, drag the table DirPersonUser to the Data
Sources node of the DirPerson_1 data source.
10. In the property sheet for the DirPersonUser_1 data source, set the
Relations property to Yes.
11. In the property sheet for the Fields node of the DirPersonUser_1
data source, set the Dynamic property to Yes.

6-4

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 6: Security for Developers


12. Right-click the Ranges node of the DirPersonUser_1 data source,
and select New Range.
13. In the property sheet for the new range, set the Field property to
User, and the Value property to (currentUserId()).
14. Save your changes to the query.

FIGURE 6.3 POLICY QUERY

Procedure: Creating a Security Policy


Follow these steps to create the security policy:
1. In the AOT, expand the Security node.
2. Right-click the Policies node and select New Security Policy.
3. In the property sheet for the security policy, set the Name property to
SmmBusRelUser, set the Label property to Limit Prospects by
User, set the Primary Table property to HcmWorker, set the
Query property to HcmWorkerUser, set the ContextType property
to RoleName, set the RoleName property to
TradeSalesRepresentative, and set the Enabled property to Yes.
4. Expand the SmmBusRelUser security policy.
5. Right-click the Constrained Tables node and select New > Add
table by relation.
6. In the property sheet for the new constrained table, set the Table
property to smmBusRelTable, set the TableRelation property to
MainContactWorker.
7. Save your changes to the policy.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

6-5

Development II in Microsoft Dynamics AX 2012


Procedure: Testing a Security Policy
Use the following steps to test the security policy.
1. Log on to Microsoft Dynamics AX as Nancy. To do this, right-click
the short-cut, while holding the Shift key down, and select Run as
Different User.
2. Enter Nancy as the user and enter the password Pa$$w0rd.
3. Open Sales and Marketing > Prospects > All prospects.
4. Only prospects with Nancy set as the sales rep are displayed.

Code Access Security


Microsoft Dynamics AX Code Access Security is used by developers to protect
Secured APIs from being invoked by un-trusted code (code that does not
originate from the AOT). Code access security does this by verifying the
following:

The code asserted the appropriate permission on the call stack to use
the secured class.

The assert (the request to use the secured class) is executed in trusted
code and saved in the AOT.

The assert is executed on the same tier as the secured class.

Code Access Security covers the use of secured classes on the server tier only.
You do not need to modify or mitigate client-only invocations of secured classes.
Code Access Security must be implemented by the secured class owner and all
consumers of the secured class. The owner secures the secured class by
implementing a specific type of permission class and calling the demand()
method on that class. Each class consumer must explicitly request permission to
invoke a secured class by calling the assert() method on the permission class.
Application code will break unless both of these steps are completed.
NOTE: Code Access Security does not guarantee the validity of any data or
parameters passed to the secured class. Data validation is still the responsibility
of the consumer.
There are six groups of protected standard classes in Microsoft Dynamics AX
Code Access Security:

6-6

Direct SQL

Run-time compilation and execution of X++

Data-controlled execution of X++

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 6: Security for Developers

File handling

Win32 Interop

Windows API

Example: Consuming a Secured Class


This example shows how to consume the TextBuffer class. The code first creates
a new FileIOPermission object, passing the filename parameter, and then calls
the assert() method.
xserver void MyServerFunction()
{
// Declare the CAS Permission object.
FileIOPermission fileIOPermission;
TextBuffer txtb = new TextBuffer();
Filename filename ="c:\\temp\\myfile.txt";
// Assert that it is okay to read and write files and
// Clipboard because the content is coming from a
static file name.
fileIOPermission = new FileIOPermission(filename,
'rw');
fileIOPermission.assert();
// From file will demand CAS permission (read)
txtb.fromFile(filename); // Read text from file
// To clipboard will demand CAS permission (write)
txtb.toClipboard(); // Copy it to the clipboard
// To file will demand CAS permission (write)
txtb.toFile(filename); // Write text to file
}

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

6-7

Development II in Microsoft Dynamics AX 2012


Example: Direct SQL
When direct SQL is used through the Connection and Statement classes, it is
subject to SQL injection threats. Note that record-level security and field-level
security are not enforced on the Statement class.
static void getCustomersDirectSQL(Args _args)
{
Connection
userConnection;
Statement
stmt;
str
sqlString;
;
userConnection = new Connection();
stmt = userConnection.createStatement();
sqlString = 'select * from custTable';
new SqlStatementExecutePermission(sqlString).assert();
stmt.executeQuery(sqlString);
CodeAccessPermission::revertAssert();
}

Display Method Authorization


A display or edit method is used to display data from another table or a
calculated value. In theory, a display method can expose any data from any table.
If a display method returns data from another table (or another row in the same
table), it poses a threat.
If a display method returns data from the same row but from another column, it
also poses a threat. For example, a user might not be allowed to view another
person's monthly salary, but could run a query to ask for the annual salary
(calculated value).

Example: Display Method Authorization


The following example is from the CustCollectionLetterJour table. This method
validates both field access and record level security.
//BP Deviation Documented
display
Addressing collectionAddress()
{
CustTable custTable;
;

6-8

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 6: Security for Developers


if (!hasFieldAccess(tableNum(LogisticsPostalAddress),
fieldNum(LogisticsPostalAddress, Address),
AccessType::View))
throw error("@SYS57330");
if (CustTable::checkExist(this.AccountNum))
{
custTable.recordLevelSecurity(true);
select firstonly Party from custTable
where custTable.AccountNum == this.AccountNum;
if (!custTable)
throw error("@SYS57330");
}
return custTable.postalAddress().Address;
}

Summary
This chapter showed how to create XDS policies to secure data based on a
predefined filter, how to assert permission for a secured API and how to secure
code in display methods.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

6-9

Development II in Microsoft Dynamics AX 2012

Test Your Knowledge


Test your knowledge with the following questions.
1. How is the table that is filtered due to an XDS policy referred to?
( ) Primary
( ) Foreign
( ) Filtered
( ) Constrained
2. Which method in the ExecutePermission class tells the AOS the programmer
has investigated the possible security implications of the code that follows
the command and has assessed that it is safe?
( ) Allow
( ) Permit
( ) Assert
( ) Revert

6-10

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

Chapter 6: Security for Developers

Quick Interaction: Lessons Learned


Take a moment and write down three key points you have learned from this
chapter
1.

2.

3.

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

6-11

Development II in Microsoft Dynamics AX 2012

Solutions
Test Your Knowledge
1. How is the table that is filtered due to an XDS policy referred to?
( ) Primary
( ) Foreign
( ) Filtered
() Constrained
2. Which method in the ExecutePermission class tells the AOS the programmer
has investigated the possible security implications of the code that follows
the command and has assessed that it is safe?
( ) Allow
( ) Permit
() Assert
( ) Revert

6-12

Microsoft Official Training Materials for Microsoft Dynamics


Your use of this content is subject to your current services agreement

S-ar putea să vă placă și