Microsoft
Dynamics Ax Macros
In MorphX macros are not
commonly used. A few places make use of macros such as keeping track of the
list of fields stored when using dialogs. It is recommended only to use macros
to define constants. Also supports code, but is not recommended as reusing code
from macros is not flexible.
The main difference between a macro and a method is that a macro
has no variable declaration part, and the code in a macro is not validated for
errors before executed from a method. This is another reasons for not putting
code in macros.
When using macros in your code, the macros must be declared
after the variable declaration. And the common place to put the definition is
in the ClassDeclaration of a class, form or a report. This will make the macro
definition available for all parts of the object.
Macro commands:
For writing macros a set of simple macro commands are used.
Below are few examples.
Command
|
Description
|
#define
|
Used to define a constant.
|
AxExample: See macro HRMConstants.
|
|
Syntax: #define.myConstant100('100')
|
|
#if.empty
|
Will return true if the macro has not been called with the
parameter validated in the statement.
|
#if.notempty
|
Will return true if the macro has been called with the parameter
validated in the statement.
|
AxExample: See macro InventDimJoin
|
|
Syntax: #if.notempty(%3)
print %3; #endif |
|
#endif
|
Ends a #if.empty or a #if.notempty statement.
|
AxExample: See macro InventDimJoin
|
|
Syntax: #endif (following any if statement)
|
|
#globalmacro
|
No difference whether declaring the start of a macro with
#localmacro or #globalmacro. #globalmacro is not used in the standard
package, consider using #localmacro instead.
|
#localmacro
|
Specify the start of a local macro.
|
AxExample: See macro BOM
|
|
Syntax: #localmacro.BOMDateSelect
(((BOM.fromDate <= %1 || ! BOM.fromDate) && (BOM.toDate >= %1 || ! BOM.toDate)) || ! %1 ) #endmacro |
|
#endmacro
|
Ends a #LOCALMACRO or a #GLOBALMACRO.
|
#linenumber
|
Returns the current line number of the macro. Can be used while
debugging, but not of must use.
|
#macrolib
|
Used to load an AOT macro from code.
|
AxExample: See class method BOMHierarchy.searchDownBOM()
|
|
Syntax: #macrolib.MyMacro
|
|
#undef
|
Undefine a constant declared with #DEFINE. A defined constant
cannot be used if #undef is called with the define name.
|
Syntax: #define.MyConstant(100)
print #MyConstant; #undef.MyConstant print #MyConstant; // will fail, as #MyConstant is not defined. |
Defining Constants:Instead of using text in your code it is strongly recommend
defining your text as constants. Often you will need an integer or a text for
setting a value. If you are going to set RGB color it is not easy to read the
following:
myStringColor(255, 255, 255)
Instead you should consider defining a constant with a
descriptive name:
myStringColor(#RBGColorWhite)
Using a macro as a constant rather than entering the value in
code makes it easier to maintain. A good way to organize the constants used in
your modifications is by creating a macro in the AOT for keeping all your
constants in one place, one good example is HRMConstants.
Creating Macros:
Macros are either created directly in the code, or put in an AOT
macro and then the AOT macro is declared in the code.
Example(1): #localmacro created in the code
static void
Macros_LocalMacro(Args _args)
{
CustTable custTable;
;
#localmacro.selectCustTable //Macro
definition starts here
#ifnot.empty(%1)
while select %1
#ifnot.empty(%3)
order by %3
#endif
{
info(queryValue(%1.%2));
}
#endif
#if.empty(%1)
info("No table
specified.");
#endif
#endmacro //Macro definition
ends here
#selectCustTable(CustTable,
accountNum) //Calling
Macro with valid parameters
#selectCustTable //Calling Macro
with no parameters – output will be text “No table specified” as per the
validation.
}
The macro will select
records from a table ‘CustTable’ and print a field from the same as the table
to be fetched, and the fields (%1, %2, %3) to be printed are specified in the
parameters for the first Macro call.
In the second Macro call, the table has not been specified so text will be printed to the Infolog.
In the second Macro call, the table has not been specified so text will be printed to the Infolog.
As you cannot declare variables in a macro, integer values
prefixed with a percentage sign such as %1 are used instead. This is the common
way of using the macros. The validations must be before calling the macro.
Notice that you can call a macro without entering the parentheses after the
macro name.
Example(2): Create and use an AOT Macro
If your macro is going to be used in several places it would
make sense creating the macro in the AOT as you will then be able to reuse the
macro.
To create a new macro in the AOT:
To create a new macro in the AOT:
1.
Unfold the Macro node,
right-click and choose New Macro.
2.
A new empty macro node
will be created. You can rename the new macro by opening the property sheet to
“MyFirstMacro”
3.
Now paste the code of the
#localmacro (from above) to your new macro.
4.
Save the Macro, and it is
ready to use.
To use the macro created in the AOT the macro command #macrolib
is used. Here the AOT macro is name MyFirstMacro, and it can be used in the
code as shown below.
static void
Macros_MacroLib(Args _args)
{
CustTable custTable;
;
#macrolib.MyFirstMacro
#selectCustTable(CustTable,
accountNum)
#selectCustTable
}
Even this will result in the same output as explained above, the
only difference is that we are calling a Macro created in AOT using #macrolib
command.
No comments:
Post a Comment