• Skip to main content
  • Skip to primary sidebar
  • Home
  • About
  • Recommended Readings
    • 2022 Book Reading
    • 2023 Recommended Readings
    • Book Reading 2024
    • Book Reading 2025
    • Book Reading 2026
  • Supply Chain Management Guide
  • PKM
  • Microsoft Excel
  • Microsoft Copilot in Office 365
  • Public Wiki Page

Ali Raza Zaidi

A practitioner’s musings on Dynamics 365 Finance and Operations

X++

Performance-First Coding Best Practices for D365 Finance & Operations

September 19, 2026 by alirazazaidi

Writing code that works is only the first step in Dynamics 365 Finance & Operations development. In enterprise implementations, customizations must also be efficient, maintainable, scalable, and aligned with D365 F&O best practices.

Some performance-oriented practices may initially appear to require additional development effort. However, the objective should not be to write the shortest possible code. The objective is to write code that performs efficiently when processing real production volumes.

This article focuses on two areas that frequently affect code quality and performance:

  • Variable declarations and scope
  • Database access using X++ select statements

1. Variable Declaration and Scope

Older Dynamics AX development commonly followed the pattern of declaring most variables at the beginning of a method. In modern X++ development, variables should generally be declared closer to where they are actually required.

Keep Variables Close to Their Usage

Avoid declaring every variable at the top of a method when it is only required much later.

For example, instead of:

public void processOrder()
{
    SalesTable salesTable;
    SalesLine salesLine;
    AmountCur totalAmount;
    boolean isValid;

    // Other processing...

    totalAmount = salesTable.SalesBalance;
}

prefer declaring variables where they become relevant:

public void processOrder()
{
    // Other processing...

    AmountCur totalAmount = salesTable.SalesBalance;
}

This makes the code easier to read and reduces unnecessary variable scope.

Limit the Scope of Variables

A variable should exist only within the scope where it is required.

Smaller scopes provide several benefits:

  • Improved readability
  • Reduced accidental reuse
  • Easier debugging
  • Clearer ownership of values
  • Better maintainability

This applies to primitive types, extended data types, enums, classes, and table buffers.

Declare Table Buffers Only When Required

Table buffers should not be created simply because they might be needed later.

Declare them when they are actually required and, where appropriate, reuse an existing buffer rather than introducing unnecessary additional buffers.

Instead of maintaining multiple buffers for the same purpose, first consider whether the existing buffer can safely be reused.

Be Careful with Variables Inside Loops

If the same variable or object is required repeatedly during loop processing, consider whether it should be declared outside the loop.

For example:

AmountCur lineAmount;

while select SalesLine
    where SalesLine.SalesId == salesTable.SalesId
{
    lineAmount = SalesLine.LineAmount;

    // Process amount
}

The important point is not simply “inside versus outside” the loop. The declaration should reflect the required scope and avoid unnecessary repeated initialization of objects or expensive resources.

Remove Unused Variables

Unused declarations should always be removed.

They increase code noise, make reviews more difficult, and can create confusion about whether a variable has a purpose that is no longer obvious.

A clean method should contain only the variables required by its current implementation.


2. Optimize Database Access

Database access is one of the most important performance considerations in D365 Finance & Operations.

Poorly designed queries may work perfectly with a small development database but become expensive when executed against millions of production records.

The basic principle is simple:

Retrieve only the data you need, and minimize unnecessary database round trips.

Select Only the Required Fields

Avoid retrieving an entire record when only a small number of fields are required.

Instead of:

select firstonly custTable
    where custTable.AccountNum == _accountNum;

consider selecting only the required fields:

select firstonly AccountNum, Name
    from custTable
    where custTable.AccountNum == _accountNum;

This makes the intention of the query clearer and avoids retrieving unnecessary data.

This practice becomes particularly valuable for large tables and performance-sensitive processing.


Avoid Unnecessary find() Calls

Standard table find() methods are convenient and have legitimate uses. However, they should not automatically be the default choice in performance-sensitive code.

For example:

custTable = CustTable::find(_accountNum);

If the customization requires only one or two fields, an explicit query may communicate the requirement more clearly:

select firstonly AccountNum, Name
    from custTable
    where custTable.AccountNum == _accountNum;

The important consideration is understanding what the underlying method does and whether it retrieves or processes more information than the customization actually requires.


3. Reduce Database Round Trips with Joins

A common performance problem is executing multiple database queries when the required information can be retrieved through a single joined query.

For example, code may first retrieve a sales order and then execute another query to retrieve related customer information.

Instead, consider combining the operations:

select firstonly SalesId, CustAccount
    from salesTable
    join AccountNum, Name
        from custTable
    where salesTable.SalesId == _salesId
       && custTable.AccountNum == salesTable.CustAccount;

The general principle is:

Prefer one well-designed query over several sequential database calls when the data can naturally be retrieved together.

Reducing database round trips becomes increasingly important in batch processing, integrations, reports, and high-volume transactions.


4. Use exists join When You Only Need to Check Existence

Sometimes a related table is required only to determine whether a matching record exists.

In such cases, there is no reason to retrieve fields from that table.

Instead of retrieving unnecessary related data, use an exists join:

select firstonly AccountNum
    from custTable
    exists join salesTable
    where salesTable.CustAccount == custTable.AccountNum
       && salesTable.SalesStatus == SalesStatus::Backorder;

An exists join is particularly useful when:

  • No fields are required from the related table.
  • The related table is used only as a filter.
  • You only need to confirm that a matching record exists.

Choose the join type based on the data requirement rather than automatically using join or outer join.


5. Understand Table Methods Before Calling Them

Table methods can improve encapsulation and reuse, so they should not be avoided simply because they are methods.

However, developers should understand the cost of the methods they call.

A method that appears simple may internally:

  • Execute additional SQL queries
  • Call another table’s find() method
  • Perform calculations
  • Traverse related records
  • Execute business logic that is unnecessary for the current scenario

This becomes especially important when a method is called repeatedly inside a loop.

For example:

while select salesLine
{
    value = salesLine.someMethod();
}

If someMethod() performs a database query, processing 10,000 sales lines could potentially generate thousands of additional database operations.

Before using such methods in performance-critical processing, review their implementation.

If the method contains important business logic, reuse it appropriately. If it merely retrieves simple data that can efficiently be included in the main query, consider retrieving that information as part of the original query.


6. Use Guard Clauses Before Expensive Operations

Validation should happen as early as possible.

Before executing a database query, determine whether the input already tells you that processing should stop.

Instead of:

select firstonly salesTable
    where salesTable.SalesId == _salesId;

if (!_salesId)
{
    return;
}

validate first:

if (!_salesId)
{
    return;
}

select firstonly SalesId
    from salesTable
    where salesTable.SalesId == _salesId;

This pattern is commonly known as a guard clause.

Guard clauses are useful for checking:

  • Missing parameters
  • Invalid enum values
  • Empty record identifiers
  • Unsupported statuses
  • Disabled functionality
  • Conditions that make further processing unnecessary

The principle is straightforward:

Do not query the database when you already know that no processing is required.


7. Be Especially Careful with Queries Inside Loops

One of the most important areas to review in X++ code is database access inside loops.

Consider:

while select salesLine
{
    custTable = CustTable::find(salesLine.CustAccount);

    // Processing
}

If thousands of records are processed, this pattern may result in a large number of database calls.

Where possible, redesign the query using joins, set-based processing, caching, or preloaded data.

When reviewing code, always pay particular attention to:

while select
for
do while
while

and check whether database queries or expensive methods are being executed repeatedly inside them.


8. Performance Should Be Considered During Development

Performance optimization should not be treated only as a final activity after development is complete.

During implementation and code review, developers should continuously ask:

  • Am I retrieving fields that I do not need?
  • Can multiple queries be combined?
  • Is this query running inside a loop?
  • Does this method execute another database query internally?
  • Can an exists join be used?
  • Can processing stop earlier?
  • Is there a set-based alternative?
  • Will this approach still perform well with production-scale data?

A customization that works with 100 records may behave very differently with 1 million records.

Final Thoughts

Good D365 F&O development is not just about producing technically correct X++ code. It is about producing code that remains reliable and efficient as transaction volumes grow.

The key principles are:

  1. Keep variable scope small and intentional.
  2. Remove unused declarations and unnecessary buffers.
  3. Retrieve only the fields you actually need.
  4. Reduce database round trips by using appropriate joins.
  5. Use exists join when related records are required only for filtering.
  6. Understand what table methods do before using them repeatedly.
  7. Validate conditions early with guard clauses.
  8. Avoid repeated database access inside loops wherever possible.
  9. Design and review customizations with production data volumes in mind.

In D365 Finance & Operations, a few milliseconds of unnecessary processing may appear insignificant during development. When the same logic runs thousands or millions of times in production, however, those small inefficiencies can become significant performance problems.

Performance should therefore be part of the design—not an afterthought.

D365 Finance and Operations Technical Training Day 6, 7 and 8

August 9, 2026 by alirazazaidi

While writing this post the couplet of Ghalib came into my mind

بازیچۂ اطفال ہے دنیا مرے آگے
ہوتا ہے شب و روز تماشا مرے آگے

ہوتا ہے نہاں گرد میں صحرا مرے ہوتے
گھستا ہے جبیں خاک پہ دریا مرے آگے

مت پوچھ کہ کیا حال ہے میرا ترے پیچھے
تو دیکھ کہ کیا رنگ ہے تیرا مرے آگے

ایماں مجھے روکے ہے، جو کھینچے ہے مجھے کفر
کعبہ مرے پیچھے ہے، کلیسا مرے آگے

So what is contribution

The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly. D365

January 26, 2026 by alirazazaidi

On new vm, I found following error, when ever, i try to create a new PR or purchase order.

Following script helped me

$AOSDirectory = ‘c:\AOSService\PackagesLocalDirectory’
$AOSBinDirectory = $AOSDirectory + ‘\bin’

[Reflection.Assembly]::LoadFrom(“$AOSBinDirectory\Microsoft.Diagnostics.Tracing.EventSource.dll”)

$sharedDLL = ‘Microsoft.Dynamics.AX.Xpp.AxShared.dll’
$subledgerDLL = ‘Microsoft.Dynamics.Subledger.Instrumentation.dll’
$taxDLL = ‘Microsoft.Dynamics.Tax.Instrumentation.dll’
$prodCfgDLL = ‘Microsoft.Dynamics.ProductConfiguration.Instrumentation.dll’
$sourceDocDLL = ‘Microsoft.Dynamics.SourceDocumentation.Instrumentation.dll’

Copy-Item $(Join-Path $AOSDirectory -ChildPath “Subledger\bin” | Join-Path -ChildPath $subledgerDLL) -Destination $AOSBinDirectory
[Reflection.Assembly]::LoadFrom($(Join-Path $AOSBinDirectory -ChildPath $subledgerDLL))
[Microsoft.Dynamics.Subledger.Instrumentation.PerformanceCounterCatalog]::Setup()

Copy-Item $(Join-Path $AOSDirectory -ChildPath “Tax\bin” | Join-Path -ChildPath $taxDLL) -Destination $AOSBinDirectory
[Reflection.Assembly]::LoadFrom($(Join-Path $AOSBinDirectory -ChildPath $taxDLL))
[Microsoft.Dynamics.Tax.Instrumentation.PerformanceCounterCatalog]::Setup()

Copy-Item $(Join-Path $AOSDirectory -ChildPath “SourceDocumentation\bin” | Join-Path -ChildPath $sourceDocDLL) -Destination $AOSBinDirectory
[Reflection.Assembly]::LoadFrom($(Join-Path $AOSBinDirectory -ChildPath $sourceDocDLL))
[Microsoft.Dynamics.SourceDocumentation.Instrumentation.PerformanceCounterCatalog]::Setup()

Copy-Item $(Join-Path $AOSDirectory -ChildPath “ApplicationSuite\bin” | Join-Path -ChildPath $prodCfgDLL) -Destination $AOSBinDirectory
[Reflection.Assembly]::LoadFrom($(Join-Path $AOSBinDirectory -ChildPath $prodCfgDLL))
[Microsoft.Dynamics.ProductConfiguration.Instrumentation.PerformanceCounterCatalog]::Setup()

[Reflection.Assembly]::LoadFrom($(Join-Path $AOSBinDirectory -ChildPath $sharedDLL))
[Microsoft.Dynamics.Ax.Xpp.AxShared.AxPerformanceCounters]::InitializePerformanceCounterCategories()

Refrence : https://blog.monsieurwinner.com/2025/11/20/d365-finance-and-operations-the-requested-performance-counter-is-not-a-custom-counter-it-has-to-be-initialized-as-readonly/

Error importing database Could not load package from .bacpac. File contains corrupted data.

September 16, 2025 by alirazazaidi

So importing the latest backup on Dev machine, I found this error
It is very strange, because I installed from

And when I run the setup from this link Error appear.

Error importing database:Could not load package from ‘C:\temp-UATbackup.bacpac’.
File contains corrupted data.

Instead to download and install DacFramework.
Download and install latest .net version and extract it to your required folder

Download and Install SqlPackage – SQL Server | Microsoft Learn

From there, instead of using the Sqlpackage.exe under C:\Program Files (x86), please use the Sqlpackage.exe in C:\Temp\Sqlpackage-dotnetBoomb

Your import query will look like below

C:\Temp>SqlPackage.exe /a:import /sf:D:\Temp\UTup.bacpac /tsn:localhost /tdn:AxDB_fromProd1 /p:CommandTimeout=0

Error Log level – Error | Infolog diagnostic message: ‘Cannot create a record in Entity (DMFEntity) – D365 Finance and operations

July 10, 2025 by alirazazaidi

During development, I initially used the arbitrary name for the custom data entity. Later, during the review session, I updated the Label property of the data entity to align with proper naming conventions.

🔍 Best practice: Always use the label for the data entity display name, not hardcoded strings.

Since this was a small customization, I had directly written string values in some places, bypassing the label. However, when I triggered database synchronization, I encountered the following error:


❌ Error Message:

Error Log level - Error | Infolog diagnostic message:
'Cannot create a record in Entity (DMFEntity). 
Entity: ProductCreationValidationEntityV2, DSTProductCreationValidationStaging.'

🧪 Root Cause:

Upon investigation, I found that the DMFEntity table contained multiple entries with conflicting labels for the same data entity names. This typically occurs when:

  • You change the label or name of a data entity without cleaning up old records
  • The model or metadata has inconsistencies after refactoring

✅ Solution:

You need to identify and delete the duplicate or orphaned records from the DMFEntity table.


🔍 Sample Queries:

Run the following queries in SQL Server Management Studio (SSMS) against your AXDB database:

-- View existing records for the custom entities
SELECT * FROM DMFENTITY WHERE ENTITYNAME = 'ProductCreationValidationEntityV2';
SELECT * FROM DMFENTITY WHERE ENTITYNAME = 'ProductCreationValidationEntityV2Lines';
SELECT * FROM DMFENTITY WHERE ENTITYNAME = 'DSTProductCreationValidationEntity';

-- Delete the orphan/conflicting records
DELETE FROM DMFENTITY WHERE ENTITYNAME = 'ProductCreationValidationEntityV2';
DELETE FROM DMFENTITY WHERE ENTITYNAME = 'ProductCreationValidationEntityV2Lines';
DELETE FROM DMFENTITY WHERE ENTITYNAME = 'DSTProductCreationValidationEntity';

⚠️ Warning: Always take a database backup before running any DELETE operation.


🧰 Next Steps:

  • Perform a full build of your model
  • Run database synchronization again
  • Re-deploy the data entities, if required

Sales price and discount is not added to sales line X++

May 26, 2025 by alirazazaidi

I encountered this issue and, during troubleshooting, I discovered that the system performs an update on the sales line to retrieve sales prices and discounts. This process has a performance impact. In fact, the prices are copied from the trade agreement in Dynamics 365 for Finance and Operations

For manual price use following code snippet

 salesLine.initFromInventTable(InventTable::find(salesLine.ItemId));
 salesLine.InventDimId = inventDim.inventDimId;
                        
                        
 salesLine.SalesQty = listObject.parmSalesQty();
 salesLine.SalesPrice = listObject.parmOriginalPrice();


 salesLine.SalesUnit = _InventItemBarcode.UnitID;
 salesLine.PriceUnit = 1.00;

 if ( (listObject.parmOriginalPrice() >= listObject.parmOfferPrice()) && !(listObject.parmOfferPrice() <0) && !(listObject.parmOriginalPrice() <=0))
 {
     if (listObject.parmOfferPrice()!=0)
     {
         real _Discount =listObject.parmOriginalPrice() -listObject.parmOfferPrice();
         salesLine.LineDisc = _Discount;
     }
     else
     {

         salesLine.LineDisc = 0;
     }
 }
 salesLine.DefaultDimension =LedgerDimensionDefaultFacade::serviceMergeDefaultDimensions(salesTable.DefaultDimension,InventTable::find(salesLine.ItemId).DefaultDimension);
 salesLine.setPriceDiscChangePolicy(PriceDiscSystemSource::ManualEntry, fieldNum(salesLine, SalesPrice));
 salesLine.setPriceDiscChangePolicy(PriceDiscSystemSource::ManualEntry, fieldNum(salesLine, LineDisc));
// salesLine.setPriceDiscChangePolicy(PriceDiscSystemSource::ManualEntry, fieldNum(salesLine, LinePercent));
 salesLine.setPriceDiscChangePolicy(PriceDiscSystemSource::ManualEntry, fieldNum(salesLine, PriceUnit));


 Try
 {
     ttsbegin;
     salesLine.CreateLine(NoYes::Yes,NoYes::Yes);
ttscommit;
}
catch
{}


Json deserialize issue in service class An exception occured when invoking the operation – Type ‘Class’ is not supported by serializer. D365 Finance and operations

April 10, 2025 by alirazazaidi

Yesterday, I was working on integration, and everything was going fine. However, when I tried to retrieve a string from the DataContract, it threw an error: “Type ‘Class’ is not supported by the serializer.” The issue persisted even when I used Newtonsoft. The rest of the logic was functioning correctly.

Eventually, I discovered that the issue was due to missing AX 2012 attributes on the list’s getter/setter or parameter. Once I added those attributes, the actual getter/setter started working as expected.

 [
    DataMemberAttribute('transactions'),  
    DataCollectionAttribute(Types::Class, classStr(DSTTransactionDC))  
  ]  
  public List Parmtransactions(List _transactions = transactions)  
  {  
    transactions = _transactions;  
return transactions;
  }

I have to add following

  AifCollectionTypeAttribute('_transactions', Types::Class, classStr(DSTTransactionDC)),
  AifCollectionTypeAttribute('return', Types::Class, classStr(DSTTransactionDC))

After that getter setter become something similar

 [
    DataMemberAttribute('transactions'),  
    DataCollectionAttribute(Types::Class, classStr(DSTTransactionDC)),  
    AifCollectionTypeAttribute('_transactions', Types::Class, classStr(DSTTransactionDC)),  
    AifCollectionTypeAttribute('return', Types::Class, classStr(DSTTransactionDC))  
  ]  
  public List Parmtransactions(List _transactions = transactions)  
  {  
    transactions = _transactions;  
 return transactions;
  }

after this change, datacontract easily serialise. 
Also change attribute at class header from datacontracattribute to dataContract.

Hope you like this post.

How to fetch un-Invoiced Delivery notes for sales order – D365 Finance and Operations

March 1, 2025 by alirazazaidi

So here is another code snippet, that I develop after two hours of testing and understanding the D365 F&O that get all non invoiced , delivery notes or packingslip. I want to restrict the code to invoice against Delivery note, If no non posted delivery note exists, Code will not generate the invoice.

 public static str getUninvoicedPackingSlipsBySalesId(SalesId _salesId)
 {
     CustPackingSlipJour custPackingSlipJour;    // Packing slip journal
     InventTrans         inventTrans;            // Inventory transaction

     str packingSlipIds = "";
     container distinctPackingSlips;             // Container to store unique Packing Slip IDs
     int i = 0;

     // Fetch only un-invoiced Packing Slips based on Sales ID
     while select inventTrans
     where inventTrans.InvoiceId == ""
     
     join custPackingSlipJour
     where custPackingSlipJour.PackingSlipId == inventTrans.PackingSlipId
       && custPackingSlipJour.SalesId == _salesId
     {
         // Check if the Packing Slip ID is already in the container
         if (conFind(distinctPackingSlips, custPackingSlipJour.PackingSlipId) == 0)
         {
             distinctPackingSlips += custPackingSlipJour.PackingSlipId;  // Add to container if unique
                          
         }
     }

     return con2Str(distinctPackingSlips);  // Return the comma-separated string or empty if none found
 }

How to convert utcdate time to ISO 8601 Formats D365 Finance and Operations

January 26, 2025 by alirazazaidi

Hi friends, recently I got chance to write a code to convert Utc date time to iso 8601. I wrote following code snippet you can modify as per your need

public static str GetEPochTime(utcdatetime _DateTimeValue)
{
    utcDateTime utcDateTimeValue;
    str formattedDateTime;
  
    date datepart;
    int milliseconds;
    TimeOfDay _time;
    // _DateTimeValue = DateTimeUtil::applyTimeZoneOffset(_DateTimeValue, Timezone::GMTPLUS0300KUWAIT_RIYADH); // Adjust for specific timezone if needed
    int _year= DateTimeUtil::year(_DateTimeValue);
    int _day = DateTimeUtil::day(_DateTimeValue);
    int _Month = DateTimeUtil::month(_DateTimeValue);
    int _Hour = DateTimeUtil::hour(_DateTimeValue);
    int _second = DateTimeUtil::second(_DateTimeValue);
    int _minute = DateTimeUtil::minute(_DateTimeValue);
    int _timetomilliSecond = 0;
    var localTime =  new System.DateTime(_year, _Month, _day, _Hour, _minute, _second,_timetomilliSecond, System.DateTimeKind::Utc);
    localTime =System.TimeZoneInfo::ConvertTime(localTime,System.TimeZoneInfo::FindSystemTimeZoneById("Arabic Standard Time"));
    // Example UTC DateTime
    // utcDateTimeValue = _DateTimeValue;
    formattedDateTime = localTime.ToString("o");
    // formattedDateTime =DateTimeUtil::toStr(_DateTimeValue);
    formattedDateTime =strReplace(formattedDateTime,".0000000",".00+03:00");
    return formattedDateTime;

Sales order cancellation validation through event handler X++

November 30, 2024 by alirazazaidi

Hi friends, small tip, I got chancel to add validation in Cancel functionality of D365 Finance and operations.Interestingly the menu button called the class. So I have to write the pre event handler for main method.

Following is the [[Code Snippet]]

public static void SalesCancelOrder_Pre_main(XppPrePostArgs _args)
    {
     

        Args args =_args.getArg("args");
        SalesTable salesTable = args.record();
        CustmTable _Response;

        select * from _Response where _Response.PrimaryKey == salesTable.SalesId && _Response.TransType == CustmTransType::SalesOrder;
         
        if (_Response.RecId !=0)
        {
           // validateEventArgs.parmValidateResult(false);
           Error("This sales order is integrationed with wms, Cancellation is not recommended, use the cancellation dailog for Cancel in wms.");
            if (Box::yesNo("Sales order is integrated with WMS, Do you really want to cancel it.", DialogButton::No) == DialogButton::No)
            {
                throw Exception::Error;
            }
        }

       
    }

Next Page »

Primary Sidebar

About

I am Dynamics AX/365 Finance and Operations consultant with years of implementation experience. I has helped several businesses implement and succeed with Dynamics AX/365 Finance and Operations. The goal of this website is to share insights, tips, and tricks to help end users and IT professionals.

Legal

Content published on this website are opinions, insights, tips, and tricks we have gained from years of Dynamics consulting and may not represent the opinions or views of any current or past employer. Any changes to an ERP system should be thoroughly tested before implementation.

Categories

  • Accounts Payable (2)
  • Advance Warehouse (2)
  • AI (3)
  • Asset Management (3)
  • Azure Functions (1)
  • Books (6)
  • Certification Guide (3)
  • ChatGPT (3)
  • Claude (1)
  • Customization Tips for D365 for Finance and Operations (65)
  • D365OF (60)
  • Data Management (1)
  • database restore (1)
  • Dynamics 365 (59)
  • Dynamics 365 for finance and operations (139)
  • Dynamics 365 for Operations (176)
  • Dynamics AX (AX 7) (134)
  • Dynamics AX 2012 (274)
  • Dynamics Ax 2012 Forms (13)
  • Dynamics Ax 2012 functional side (16)
  • Dynamics Ax 2012 Reporting SSRS Reports. (31)
  • Dynamics Ax 2012 Technical Side (52)
  • Dynamics Ax 7 (65)
  • Exam MB-330: Microsoft Dynamics 365 Supply Chain Management (7)
  • Excel Addin (1)
  • Favorites (12)
  • Financial Modules (6)
  • Functional (8)
  • General Journal (1)
  • Implementations (1)
  • Ledger (1)
  • Lifecycle Services (2)
  • Logseq (4)
  • Management Reporter (1)
  • Microsoft Excel (4)
  • MS Dynamics Ax 7 (64)
  • MVP summit (1)
  • MVP summit 2016 (1)
  • New Dynamics Ax (19)
  • Non Defined (9)
  • Note taking Apps (2)
  • Obsidian (4)
  • Personal Knowledge Management (3)
  • PKM (16)
  • Power Platform (6)
  • Procurement (5)
  • procurement and sourcing (6)
  • Product Information Management (4)
  • Product Management (6)
  • Production Control D365 for Finance and Operations (10)
  • Sale Order Process (10)
  • Sale Order Processing (10)
  • Sales and Distribution (5)
  • Soft Skill (1)
  • Supply Chain Management D365 F&O (5)
  • Tips and tricks (278)
  • Uncategorized (165)
  • Upgrade (1)
  • Web Cast (7)
  • White papers (4)
  • X++ (12)

Wiki

  • SCM

Copyright © 2026 · Magazine Pro On Genesis Framework · WordPress · Log in