Saturday, June 30, 2018

Select count(*) sum(Field) from MyTable

The below select query will give the both the Sales Line record count and the sum of sales quantity.
static void Test_Data(Args _args)
{    
   SalesLine  salesLine;
   select count(RecId),sum(SalesQty) from salesLine;
   info(strFmt("Number of Records : %1  Total Quantity : %2",SalesLine.RecId,SalesLine.SalesQty));
}

Best Regards,
Hossein Karimi

Pass field value from SalesTable to CustTrans

Follow the steps below,
1) Create a new field (If not already existing)
2) Create the parm method for that field on CustVoucher class
3) Assign value to this parm method in SalesInvoiceJournalPost.postCustVend() method by using the salesTable buffer
4) Add the code for assigning the variable value(or the parm method value) in CustVoucher.initCustVendTrans() method.
Best Regards,
Hossein Karimi

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.


NOTE: In X++ one class can extend another class, and one extended data type
can extend another.
Extend a ClassTo 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
{
}

Objects created from the ChildHave 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, Method4the Child can have two of those methods overridden, plus an additional method.Method1, Method3, Method5If 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.

Best Regards,
Hossein Karimi

Friday, June 29, 2018

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 ClassesA 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.

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.


Demonstration: Create Variables in the ClassPerform 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 ClassPerform 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.


Best Regards,
Hossein Karimi

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.

The following is an example of the OK/Cancel 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


Best Regards,
Hossein Karimi

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:
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

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

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.

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");

The following figure shows the error Infolog message .


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.


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");
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.
 

Best Regards,
Hossein Karimi

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 textThe title bar textHelp 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");
The following figure shows the resulting window.



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.

The following example shows a YesNo box:Box::yesNo("Choose Yes or No", DialogButton::Yes, "Yes No
Box Example", "Answer Yes or No");

The resulting box is shown on the display .



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.


Best Regards,
Hossein Karimi

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.


Best Regards,
Hossein Karimi

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.
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 continuestatement 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


Best Regards,
Hossein Karimi

For Loop

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
forstatement 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.


Best Regards,
Hossein Karimi

Do while loop

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);


Best Regards,
Hossein Karimi

While loop

WhileThe 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;
}

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.


Best Regards,
Hossein Karimi

Switch Statement

A switch statement acts as a multi-branch control statement that defines an
expression and whose result leads to a specific program execution. The
switchstatement 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':
Statement1;
Statement2;
break;
case 'Choice2':
Statement3;
break;
case 'Choice3':
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.

The following example compares a switch statement with an if…else 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 : grade = "A";
message = "Excellent";
break;
case 80 : grade = "B";
message = "Good";
break;
case 70 : grade = "C";
message = "Average";
break;
case 60 : grade = "D";
message = "Poor";
break;
default : grade = "Failed!";
message = "You need to study more!" ;
}
This example produces the same result as the previous example, but uses if...elsestatements 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
{

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
switchstatement is allocating multiple results of the expression to one outcome or case.
The following example shows the use of multiple expressions in a
switchstatement.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";
}


Best Regards,
Hossein Karimi

Ternary Operator

This conditional statement behaves exactly like an if…else statement. The main
reason to use the ternary operator is convenience in coding. Its syntax is as
follows:
condition ? statement1 : statement2;
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 i = 12;
int j = 10;
int max;
max = i > j ? i : j;


Best Regards,
Hossein Karimi

If Statement

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;
}


If...elseAn if statement checks for only one possibility and ignores all other conditions.
An
if…else statement checks one condition and if true, the block of code is
executed. Otherwise, an alternative statement is executed. The syntax for an
if…else statement is as follows:
if (condition)
{
//if true these statements are executed
}
else
{
//if false these statements are executed
}
int i = 12;
int j = 10;
int 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
if…else...if statement. The syntax for this statement
is as follows:
if (condition1)
{
//statement1
}
else
{
if (condition2)
{
//statement2
}
else
{
//statement3
}
}

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 examPass 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 passExam = true;
boolean passHomeWork = false;
str studentStatus;
if (passExam == true)
{
if (passHomeWork == true)
{
studentStatus = "Passed";
}
else
{
studentStatus = "Failed";
}
}
else
{
studentStatus = "Failed";
}


Best Regards,
Hossein Karimi

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 statementSwitch statementTernary operators
All these statements are evaluated using operators.

Best Regards,
Hossein Karimi

Relational Operators

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

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.


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 = += -=

Best Regards,
Hossein Karimi

Relational Operators

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

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.

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.


Best Regards,
Hossein Karimi

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 not
operation.
& 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)


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.
 "

Best Regards,
Hossein Karimi

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 OperatorsAssignment operators modify the contents of a variable or field. The following
table defines available operators.
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.

Best Regards,
Hossein Karimi

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.


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


Best Regards
Hossein Karimi 

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 realUnlimtedArray[]; // Unlimited index values
real realLimitedArray[10]; // maximum of 10 values
realLimitedArray[2] = 3.142;


Best Regards,
Hossein Karimi 

Thursday, June 28, 2018

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


Data Model Object Model
Classes (extended and referenced)
All Extended Data Types
All Base Enums
All X++ Data Types

Procedure: Reverse Engineering an Object ModelPerform 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 ModelPerform 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


Best Regards,
Hossein Karimi

Wednesday, June 27, 2018

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'sTasks 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.

Best Regards,
Hossein Karimi

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;
}
}

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


Best Regards,
Hossein Karimi

Compare

Use the compare tool to highlight differences between versions of a single
element:
In two different layersIn an old version of an elementIn two different elementsAn element that will be imported
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.


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 ToolPerform the following steps to use the compare tool.
1. Open the AOT.
2. Expand the
Classes node.
3. Expand the
Activities class.
4. Double-click the Construct method.
5. Add the following line of code:
// Compare tool demonstration6. Press F8 to compile and save.
7. Right-click the
Activities class.
8. Select
Compare to open the compare tool.
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.


Best Regards,
Hossein Karimi  

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:


To turn debugging off, you can visit Tools > Options, and select the Developertab. 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.
 
Use the toolbar located above the Output window to navigate through the code
and perform other actions.


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
Sourcewindow.

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 Configuration4. In the Configuration Name, enter a name, for example AOS_Debug.
5. Click
OK6. Check the box Enable breakpoints to debug X++ code running on
this Server
 
7. Click Apply8. 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.


Regards,
Hossein Karimi

Configure the Firewall on the Enterprise Portal Server

After you install Enterprise Portal, enable Web Server (HTTP) in Windows Firewall. If you do not enable the web server in Windows Firewall...