Ax2012 Enus Devii 03

download Ax2012 Enus Devii 03

of 28

Transcript of Ax2012 Enus Devii 03

  • 8/11/2019 Ax2012 Enus Devii 03

    1/28

    Chapter 3: Objects and Classes

    3-1

    CHAPTER 3: OBJECTS AND CLASSES

    Objectives

    The objectives are:

    Use the classes within Microsoft DynamicsAX 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 scopingrules.

    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 modifyingcode 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 ispossible 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.

  • 8/11/2019 Ax2012 Enus Devii 03

    2/28

    Development II in Microsoft DynamicsAX 2012

    3-2

    Classes

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

    Variablesare used to store the data for the class. They are specific to

    an object; every object instantiated from the class declaration has itsown copy of the variable. Such variables are known as instance

    variables.

    Methodsare the functions that operate on the data and define theobject's behavior. They are often declared to operate on the instancevariables 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 behaveswhen 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 necessaryvariables. 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. Thismeans 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 assignvalues to object variables using this method.

    Finalize():This method terminates the object. It is never used withinthe 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.

  • 8/11/2019 Ax2012 Enus Devii 03

    3/28

    Chapter 3: Objects and Classes

    3-3

    Demonstration: Create a Class in the Application ObjectTree

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

    3. Right-click the Classesnode and select New Classin the contextmenu. A new class named Class1is created and contains one node:

    the classDeclarationnode. 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 classDeclarationnode.

    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.

  • 8/11/2019 Ax2012 Enus Devii 03

    4/28

    Development II in Microsoft DynamicsAX 2012

    3-4

    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. Open the AOT.

    2. Find the Classes node.

    3. Right-click and select New Class.

    4. Expand the node for the newly created class.

    5. Double-click the classDeclaration.

    6. Rename the class to PrintMyName.

    7. Declare a variable of type String, called "myName".

    8. Press F8to compile and save the classDeclaration.

    9. Right-click the class and select New Method.

    10.Double-click the new method.

    11.Rename the method to "setMyName".

    12.Enter the code in the setMyNamemethod shown below into your

    method.13.Press F8to compile and save the method.

    14.Right-click the class and select New Method.

    15.Double-click the new method.

    16.Rename the method to "printMyName".

    17.Enter the code in the printMyNamemethod show below into yourmethod.

    18.Press F8to compile and save the method.

  • 8/11/2019 Ax2012 Enus Devii 03

    5/28

    Chapter 3: Objects and Classes

    3-5

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

    Protectedallows the method to be called only by methods in thesame class or subclasses of the class in which the method is defined.

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

  • 8/11/2019 Ax2012 Enus Devii 03

    6/28

    Development II in Microsoft DynamicsAX 2012

    3-6

    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. Open the AOT.2. Find the class created in the previous lab.

    3. Double click each method in the class.

    4. Change the method modifier from Private to Public.

    5. Save the changes.

  • 8/11/2019 Ax2012 Enus Devii 03

    7/28

    Chapter 3: Objects and Classes

    3-7

    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

    {

    }

  • 8/11/2019 Ax2012 Enus Devii 03

    8/28

    Development II in Microsoft DynamicsAX 2012

    3-8

    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 Childthat 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 documentsopen 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.

  • 8/11/2019 Ax2012 Enus Devii 03

    9/28

    Chapter 3: Objects and Classes

    3-9

    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.

  • 8/11/2019 Ax2012 Enus Devii 03

    10/28

    Development II in Microsoft DynamicsAX 2012

    3-10

    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. Open the AOT.

    2. Find the Jobs node.

    3. Right-click select New Job.

    4. Type the following code into the job.

    PrintMyName PrintMyName;

    PrintMyName = new PrintMyName();

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

    5. Press F5to compile and run the job.

  • 8/11/2019 Ax2012 Enus Devii 03

    11/28

    Chapter 3: Objects and Classes

    3-11

    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 abcis declared in the classDeclaration of ANewClassand variable xyz

    is declared in aNewMethod. The variable xyz can only be used within the scopeof 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 _parm1, int _parm2= 1)

    {

    }

  • 8/11/2019 Ax2012 Enus Devii 03

    12/28

    Development II in Microsoft DynamicsAX 2012

    3-12

    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 voidwith an Extended Data Type to specify the type ofdata to receive from the method. Any kind of data can be returned

    including table buffers and class objects.

    Write returnfollowed by a specification of the data that you want toreceive for any manipulation of the data.

    private description getStringValue()

    {

    description myTxt = "Text";

    return myTxt;

    }

  • 8/11/2019 Ax2012 Enus Devii 03

    13/28

    Chapter 3: Objects and Classes

    3-13

    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. Open the AOT.

    2. Find the class created earlier in this lesson that prints your name.

    3. Double-click the method setMyName().

    4. Modify the code so the method looks the same as shown in thefollowing example.

    5. Press F8to save and compile the code.

    6. Find the job in the AOT that executes the class.

    7. Modify the job so that the line that calls the setMyName() method iscalled with your name.

    8. Press F5to 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;

    }

  • 8/11/2019 Ax2012 Enus Devii 03

    14/28

    Development II in Microsoft DynamicsAX 2012

    3-14

    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 ThisA class has a method called myMethod() and another called run(). The run()

    method calls the myMethod() method.

    public void run()

    {

    this.myMethod();

    }

  • 8/11/2019 Ax2012 Enus Devii 03

    15/28

    Chapter 3: Objects and Classes

    3-15

    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. Open the AOT.

    2. Find the class created earlier in this lesson that prints your name.

    3. Right-click the class and select New Method.

    4. Modify the code so the method looks the same as shown in thefollowing example.

    5. Press F8to save and compile the code.

    6. Find the job in the AOT that executes the class.

    7. Modify the job to the code shown in the following example.

    8. Press F5to 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;

    }

  • 8/11/2019 Ax2012 Enus Devii 03

    16/28

    Development II in Microsoft DynamicsAX 2012

    3-16

    Method Types

    There are many different types of methods. Some of the more common types are

    discussed as follows.

    Static MethodsStatic 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 mainmethod 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.

    Argsis 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 argsclass containing those property values is passed to the

    mainmethod using the argsparameter.

  • 8/11/2019 Ax2012 Enus Devii 03

    17/28

    Chapter 3: Objects and Classes

    3-17

    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;

  • 8/11/2019 Ax2012 Enus Devii 03

    18/28

    Development II in Microsoft DynamicsAX 2012

    3-18

    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 (inclasses 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; // Fields in a table are public

    print CustTable.name; // Fields in a table can bereferred to directly

    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.

  • 8/11/2019 Ax2012 Enus Devii 03

    19/28

    Chapter 3: Objects and Classes

    3-19

    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 theimplementation 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 includesthe employee's name and date of birth, and so on.

    Delegate A delegate is the definition of the information passed from theproducer 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.

  • 8/11/2019 Ax2012 Enus Devii 03

    20/28

    Development II in Microsoft DynamicsAX 2012

    3-20

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

  • 8/11/2019 Ax2012 Enus Devii 03

    21/28

    Chapter 3: Objects and Classes

    3-21

    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 mayPackingSlipBeUpdatedand addthe 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 methodmayPackingSlipBeUpdated.

    6. Right-click the method and select New Event Handler Subscription.The EventHandler1event handler node is created.

    7. In the property sheet for EventHandler1, set the Nameproperty tomayPackingSlipBeUpdatedPost, set the CalledWhenproperty to

    Post, set the Classproperty to SalesTableTypeDelegate, set the

    Methodproperty to mayPackingSlipBeUpdated.

    8. Test your modification in the sales order form and observing that thepacking slipbutton 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.

  • 8/11/2019 Ax2012 Enus Devii 03

    22/28

    Development II in Microsoft DynamicsAX 2012

    3-22

    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;

    }

    private real parmValue1(real _value1 = value1){

    value1 = _value1;

    return value1;}

    private real parmValue2(real _value2 = value2){

    value2 = _value2;return value2;

    }

  • 8/11/2019 Ax2012 Enus Devii 03

    23/28

    Chapter 3: Objects and Classes

    3-23

    public real add(){

    return value1 + value2;}

    public real subtract(){

    return value1 - value2;}

    public real multiple(){

    return value1 * value2;}

    public real divide(){

    return value1 / value2;}

  • 8/11/2019 Ax2012 Enus Devii 03

    24/28

    Development II in Microsoft DynamicsAX 2012

    3-24

    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.

  • 8/11/2019 Ax2012 Enus Devii 03

    25/28

    Chapter 3: Objects and Classes

    3-25

    Test Your Knowledge

    Test your knowledge with the following questions.

    1. Name two different types of methods that can be created in X++ and describetheir differences.

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

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

  • 8/11/2019 Ax2012 Enus Devii 03

    26/28

    Development II in Microsoft DynamicsAX 2012

    3-26

    Quick Interaction: Lessons Learned

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

    chapter

    1.

    2.

    3.

  • 8/11/2019 Ax2012 Enus Devii 03

    27/28

    Chapter 3: Objects and Classes

    3-27

    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 doesNOT return a value?

    MODEL ANSWER:

    void

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

    MODEL ANSWER:

    Main

  • 8/11/2019 Ax2012 Enus Devii 03

    28/28

    Development II in Microsoft DynamicsAX 2012