This document is a cheatsheet for Dynamics 365 AX/Op/FinOp you will frequently encounter in projects.
This guide is not intended to teach you X++ or D365 AX/Op/FinOp general development from the ground up, but to help developers with basic knowledge who may struggle to get familiar with some concepts.
Besides, I will sometimes provide personal tips that may be debatable but will take care to mention that it's a personal recommendation when I do so.
When you struggle to understand a notion, I suggest you look for answers on the following resources:
- Microsoft Docs - Official Dynamics 365 AX/Op/FinOp documentation.
- StackOverflow tag - "dynamics-365-operations" tag on StackOverflow. Currently there is not that much content there, but this is a attempt to encourage you to use it when needed.
- AX Community - AX community where thousands of questions has been asked and answered.
- #MSDyn365FO on Linkedin - Official D365FO hashtag on Linkedin.
- #MSDyn365FO on Twitter - Official D365FO hashtag on Twitter.
Links in this section refers to AX 2012, but it does apply to 365 versions. Kindly take a look at the official documentation.
See the official documentation
What relation type should I choose? Coming soon.
When importing data into AX using data entities, sometimes there is no way to match data structure between data source (xml file, excel spredsheet, etc) and AX table. For instance:
- Single line from a spredsheel source needs to be split amoung table header and table line in D365.
- Records creation is assisted by some class and cannot be directly created by DMF (Data Management Framework).
From your data entity, create a new static field following the below template:
Kindly note this is a personal quick recommendation. Obviously this code can be improved.
public static container copyCustomStagingToTarget(DMFDefinitionGroupExecution _dmfDefinitionGroupExecution)
{
CustCustomerStaging staging;
CustCustomerStaging stagingUpd;
// Iterate through all records with have not been processed
while select forupdate staging
where staging.ExecutionId == _dmfDefinitionGroupExecution.ExecutionId
&& (staging.TransferStatus == DMFTransferStatus::NotStarted || staging.TransferStatus == DMFTransferStatus::Validated)
{
try
{
ttsbegin;
// Do your stuff
staging.TransferStatus = DMFTransferStatus::Completed;
staging.update();
ttscommit;
}
catch (Exception::Error)
{
error("Something wrong has happened.");
}
}
ttsbegin;
update_recordset staging
setting TransferStatus = DMFTransferStatus::Error
where staging.DefinitionGroup == _dmfDefinitionGroupExecution.DefinitionGroup
&& staging.ExecutionId == _dmfDefinitionGroupExecution.ExecutionId
&& (staging.TransferStatus == DMFTransferStatus::NotStarted || staging.TransferStatus == DMFTransferStatus::Validated);
ttscommit;
// Method returns a container containing the quantities of inserted and updated records.
select count(RecId) from staging
where staging.DefinitionGroup == _dmfDefinitionGroupExecution.DefinitionGroup
&& staging.ExecutionId == _dmfDefinitionGroupExecution.ExecutionId
&& staging.TransferStatus == DMFTransferStatus::Completed;
return [staging.RecId, 0];
}
In order to copyCustomStagingToTarget be executed, you need to set field Set-based processing as TRUE.
Data management workspace > Data entities button
A list of few things to take into consideration before exporting a millions of records:
- Do your best to skip staging. This wont be possible if your entity has any computed field or container field. Data management will info about any other field type that is preventing your to skip staging.
- When exporting to a BYOD, make sure you have enough DTU assigned to your target Azure database.
Basically there are two types of data entities errors messages: from View excecution log message and View staging data message. View excecution log displays messages in macro way e.g. "Could not connect into system X", while View staging data displays messages to each distinct staging table record.
Any message printed during DMF execcution (info, warning and error) will end up being displayed in View excecution log area.
To display custom log message to specifics staging records, use the following snippet:
DMFStagingValidationLog::insertLogs(_dmfDefinitionGroupExecution.DefinitionGroup,
_dmfDefinitionGroupExecution.ExecutionId,
DMFEntity::find(_dmfDefinitionGroupExecution.Entity),
staging.RecId,
"",
"My custom log message",
DMFSourceTarget::Target);
- Direction: Importing
- Purpose: When importing, use it to fill either datasource or entity fields based on entity fields.
- Example: In CustCustomerEntity.mapEntityToDataSource(), EmployeeResponsibleNumber field value is used to retrive worker record id and set it into MainContactWorker field from entity itself.
Sometimes we get very generic erros while rendering reports from browser and Event Viewer doesnt help much. Checking reporting service log files is the best way to find out the reason:
C:\Program Files\Microsoft SQL Server\ SQL_INSTANCE \Reporting Services\LogFiles
You may find this addin useful.
Coming soon.
Keyboard is by far the most efficient way to input data and execute commands. Although is a good idea to get familiar with Dynamics 365 default shortcuts, they are not good. For my personal taste, a good shortcut should be:
- Performed with one hand
- Easily memorizable (easy keys/combinations)
- Ergonimic
It might be really useful to define your own shortcuts. Bellow I list how I usually setup my own in Visual Studio:
- Build models: Ctrl + Space, Ctrl + Space
- Sync database: Shift + Space, Shift + Space
- Add new item (project): Ctrl + Shift + Space, Ctrl + Shift + Space
If this project helped you in any way and you feel like supporting me: