static void Job21(Args _args)
{
int startTime = timeNow();
int endTime;
sleep(5000);
endTime = timeNow();
info(strFmt("Process took %1", timeConsumed(startTime, endTime)));
}
Wednesday, July 23, 2014
How to calculate time consumed running a process in X++
This code can be used to calculate the time consumed running a process
Setting LedgerDimension field on LedgerJournalTrans table in AX 2012 via X++ code
The following code can be used to update LedgerDimension field on the LedgerJournalTrans
RecId getDimension(str _ledgerAccount, str _businessUnit, str _costCentre, str _jurisdiction, str _subscriberType)
{
DimensionServiceProvider DimensionServiceProvider = new DimensionServiceProvider();
LedgerAccountContract LedgerAccountContract = new LedgerAccountContract();
DimensionAttributeValueContract ValueContract;
List ListValueContract = new List(Types::Class);
dimensionAttributeValueCombination dimensionAttributeValueCombination;
DimensionStorage dimStorage;
if (_businessUnit)
{
ValueContract = new DimensionAttributeValueContract();
ValueContract.parmName('BusinessUnit') ;
ValueContract.parmValue(_businessUnit);
ListValueContract.addEnd(ValueContract);
}
if (_costCentre)
{
ValueContract = new DimensionAttributeValueContract();
ValueContract.parmName('CostCentre') ;
ValueContract.parmValue(_costCentre);
ListValueContract.addEnd(ValueContract);
}
if (_jurisdiction)
{
ValueContract = new DimensionAttributeValueContract();
ValueContract.parmName('Jurisdiction') ;
ValueContract.parmValue(_jurisdiction);
}
if (_subscriberType)
{
ValueContract = new DimensionAttributeValueContract();
ValueContract.parmName('SubscriberType') ;
ValueContract.parmValue(_subscriberType);
ListValueContract.addEnd(ValueContract);
}
LedgerAccountContract.parmMainAccount(_ledgerAccount);
LedgerAccountContract.parmValues(ListValueContract);
dimStorage = DimensionServiceProvider::buildDimensionStorageForLedgerAccount(LedgerAccountContract);
dimensionAttributeValueCombination = DimensionAttributeValueCombination::find(dimStorage.save());
return dimensionAttributeValueCombination.RecId;
}
Setting Default Dimension using code in AX 2012
The following method can be used to set the default dimension e.g. on CustTable when importing data via X++
static DimensionDefault findDefaultDimension(str _businessUnit, str _costCentre, str _jurisdiction, str _subscriberType)
{
Struct struct = new Struct();
container defDimensionCon;
DimensionDefault dimensionDefault;
DimensionAttributeSetItem dimAttrSetItem;
DimensionAttribute dimAttribute;
int i;
//Read required dimensions
while select Name, BackingEntityType from dimAttribute
where dimAttribute.BackingEntityType == tableNum(DimensionFinancialTag) &&
dimAttribute.Type != DimensionAttributeType::DynamicAccount
join dimAttrSetItem
where dimAttrSetItem.DimensionAttribute == dimAttribute.RecId &&
dimAttrSetItem.DimensionAttributeSet == DimensionCache::getDimensionAttributeSetForLedger()
{
//Add the Dimension name and value to struct
if (_businessUnit && dimAttribute.BackingEntityType == tableNum(DimensionFinancialTag) && dimAttribute.Name == 'BusinessUnit')
{
struct.add(dimAttribute.Name, _businessUnit);
}
if (_costCentre && dimAttribute.BackingEntityType == tableNum(DimensionFinancialTag) && dimAttribute.Name == 'CostCentre')
{
struct.add(dimAttribute.Name, _costCentre);
}
if (_jurisdiction && dimAttribute.BackingEntityType == tableNum(DimensionFinancialTag) && dimAttribute.Name == 'Jurisdiction')
{
struct.add(dimAttribute.Name, _jurisdiction);
}
if (_subscriberType && dimAttribute.BackingEntityType == tableNum(DimensionFinancialTag) && dimAttribute.Name == 'SubscriberType')
{
struct.add(dimAttribute.Name, _subscriberType);
}
}
defDimensionCon += struct.fields();
for (i = 1; i <= struct.fields(); i++)
{
defDimensionCon += struct.fieldName(i);
defDimensionCon += struct.valueIndex(i);
}
if (struct.fields())
{
//Get the DimensionAttributeValueSet RecId
dimensionDefault = AxdDimensionUtil::getDimensionAttributeValueSetId(defDimensionCon);
}
return dimensionDefault;
}
Tuesday, June 24, 2014
Workflow Stopped (error): X++ Exception: Work item could not be created. Insufficient rights for user ?
I've had this problem a number of times and the error message doesn't give you enough information to know exactly what permissions need to be added for the user.
There are a couple of ways to determine the menu items and web menu items associated with the workflow.
The first way is to go to the AOT and look under the Workflow > Approvals node
The required display menu and web display menu items are highlighted below
The required action and web action menus are highlighted below
Check that the user has permission to access these display and action menu and webmenu items.
You can also use the Visual Studio 2010 debugger on the SysWorkflowDocument.assertAsUser() class method to locate the menu item(s) that the user doesn't have access to.
There are a couple of ways to determine the menu items and web menu items associated with the workflow.
The first way is to go to the AOT and look under the Workflow > Approvals node
The required display menu and web display menu items are highlighted below
The required action and web action menus are highlighted below
Check that the user has permission to access these display and action menu and webmenu items.
You can also use the Visual Studio 2010 debugger on the SysWorkflowDocument.assertAsUser() class method to locate the menu item(s) that the user doesn't have access to.
“SysDictEnum object not initialised” error running AIF document service creation wizard
Came across an issue with creating a new AIF document
service today. The error reported in the InfoLog was “SysDictEnum object not
initialised”, which gave me an indication of a problem with an Enum.
The stack trace occurred during the creation of one of the
document classes and by looking at the partially created class I was able to
determine the database field that was causing the problem.
A quick check of the EDT properties revealed the problem - the Enum that I had created and added to my table didn’t have an EnumType.
After correcting the Enum I was able to rerun the AIF create document service
wizard successfully this time.Wednesday, November 6, 2013
Display required license on Secuirty privileges form in AX2012
To assist with creating security roles for lower license levels (Functional, Self-serve, etc) I made a small mod to the Security prviledges form to display the license level required for each permission object. Easier than having to generate and run the license report everytime you make a change or having to lookup each permission in the AOT to see the license level.
These fields can be added by creating two new display methods on the securableObject data source on the SysSecTasksEditPS form:
The above code adds a display method to display the ViewUserAccessLincense. The other display method is exactly the same except #PropertyFullUserLicense is used instead of #PropertyReadUserLicense on the following line:
userLicType = typeSet.lookup(treeNode.AOTgetProperty(#PropertyReadUserLicense));
Then all you need to do is add the display methods to the grid in the form design and you're done
These fields can be added by creating two new display methods on the securableObject data source on the SysSecTasksEditPS form:
public display UserLicenseType displayViewUserAccessLicense(SecurableObject _object)
{
#AOT
#Properties
#define.PropertyReadUserLicense('ViewUserLicense')
#define.PropertyFullAccessUserLicense('MaintainUserLicense')
UserLicenseType userLicType;
TreeNode treeNode;
EntryPointType type = Global::enum2int(_object.Type);
str nodePath =
(type == EntryPointType::MenuItemDisplay) ? strFmt('%1\\%2', #MenuItemsDisplayPath, _object.Name) :
(type == EntryPointType::MenuItemOutput) ? strFmt('%1\\%2', #MenuItemsOutputPath, _object.Name) :
(type == EntryPointType::MenuItemAction) ? strFmt('%1\\%2', #MenuItemsActionPath, _object.Name) :
(type == EntryPointType::WebUrlItem) ? strFmt('%1\\%2', #WebMenuItemsUrlPath, _object.Name) :
(type == EntryPointType::WebActionItem) ? strFmt('%1\\%2', #WebMenuItemsActionPath, _object.Name) :
(type == EntryPointType::WebManagedContent) ? strFmt('%1\\%2', #WebContentItemsManagedPath, _object.Name) :
'';
Map typeSet = new Map(Types::String, Types::Enum);
// Available types property values
typeSet.insert('', UserLicenseType::None);
typeSet.insert('None', UserLicenseType::None);
typeSet.insert('SelfServe', UserLicenseType::SelfServe);
typeSet.insert('Task', UserLicenseType::Task);
typeSet.insert('Functional', UserLicenseType::Functional);
typeSet.insert('Enterprise', UserLicenseType::Enterprise);
typeSet.insert('Server', UserLicenseType::Server);
if (nodePath != '')
{
treeNode = TreeNode::findNode(nodePath);
}
if (treeNode)
{
userLicType = typeSet.lookup(treeNode.AOTgetProperty(#PropertyReadUserLicense));
treeNode.treeNodeRelease();
}
return userLicType;
}
The above code adds a display method to display the ViewUserAccessLincense. The other display method is exactly the same except #PropertyFullUserLicense is used instead of #PropertyReadUserLicense on the following line:
userLicType = typeSet.lookup(treeNode.AOTgetProperty(#PropertyReadUserLicense));
Then all you need to do is add the display methods to the grid in the form design and you're done
Sunday, October 27, 2013
Displaying an image on a form grid in Dynamics AX
Sometimes it is useful to display an image in a data grid on a from to highlight certain records e.g. records with validation errors as in the example below:
To achieve this requires 2 main steps:
1. Adding a display method on the table/form datasource that returns an ImageRes
2. Adding a new field control on the form by right-clicking on the Grid control within the form design and selecting New Control > Window
Set the properties of the new control as follows:
To achieve this requires 2 main steps:
1. Adding a display method on the table/form datasource that returns an ImageRes
//BP Deviation Documented
display ImageRes errorExist()
{
#resAppl;
return this.ErrorLogged ? #ImageError : #ImageBlank2;
}
2. Adding a new field control on the form by right-clicking on the Grid control within the form design and selecting New Control > Window
Set the properties of the new control as follows:
Subscribe to:
Posts (Atom)


