Pages

Tuesday, October 23, 2018

Fun and better method to get Args.Caller() name

In any AX/D365 environment, there's often a need to get the Args.Caller().Name(), except not all possible caller's will have a .name() method, so here's a little function that can be added to a form to get the caller's name in a more proper method.


private IdentifierName getCallerName()
{
    Object              caller;
    SysDictClass        sysDictClass;
    IdentifierName      callerName;

    // There must be a caller to retrieve a name
    if (!(element.args() && element.args().caller()))
        return callerName;

    caller          = element.args().caller();
    sysDictClass    = new SysDictClass(classIdGet(caller));

    // Use reflection & recursion to get the name if possible
    while (sysDictClass)
    {
        if (sysDictClass.hasObjectMethod(identifierStr(Name)))
        {
            callerName      = caller.name();
            sysDictClass    = null;
        }
        else if (sysDictClass.extend())
        {
            sysDictClass    = new sysDictClass(sysDictClass.extend());
        }
        else
        {
            sysDictClass    = null;
        }
    }

    return callerName;
}

Tuesday, April 24, 2018

How to convert a decimal to a fraction in X++ with Dynamics AX or Dynamics 365 FO

I had a customer who needed to convert a decimal to fraction, so I just translated this StackOverflow post where all credit is due. I'm sure someone else will find it useful at some point.

The two main things in the job below (details taken from StackOverflow) are "_real", which is the value you want to convert, and "_accuracy", which specifies the max relative error; not the max absolute error.

So _accuracy = 0.01 would find a fraction within 1% of the value.

I also quickly threw this job together, so I didn't test for extremely large integers or any edge cases.

Here's a simple job that demonstrates how it works.


static void KW_DecToFrac(Args _args)
{
    // Create a function that accepts these two parameters
    real                _real           = 0.45;
    real                _accuracy       = 0.01;
    
    int                 sign = _real < 0 ? -1 : (_real == 0 ? 0 : 1);
    real                maxError;
    System.Decimal      d;
    
    int n;
    int lower_n = 0;
    int lower_d = 1;
    int middle_n;
    int middle_d;
    int upper_n = 1;
    int upper_d = 1;
    int z;
    
    void f(int _N, int _D)
    {
        info(strFmt("%1/%2", _N, _D));
    }
    
    _real = abs(_real);
    
    maxError = sign == 0 ? _accuracy : _real * _accuracy;
    
    d = System.Math::Floor(_real);
    n = System.Decimal::ToInt32(d);
    
    _real -= n;
    
    if (_real < maxError)
    {
        f(sign * n, 1);
        return;
    }
    
    if (1 - maxError < _real)
    {
        f(sign * (n+1), 1);
        return;
    }
    
    while (true)
    {
        z++;
        middle_n = lower_n + upper_n;
        middle_d = lower_d + upper_d;
        
        if (middle_d * (_real + maxError) < middle_n)
        {
            upper_n = middle_n;
            upper_d = middle_d;
        }
        else if (middle_n < (_real - maxError) * middle_d)
        {
            lower_n = middle_n;
            lower_d = middle_d;
        }
        else          
        {
            f((n * middle_d + middle_n) * sign, middle_d);
            return;
        }        
    }
    
    info("Done");
}

Wednesday, April 4, 2018

[#MsDyn365FO] How to adjust your DeployablePackages cleanup duration

Microsoft automatically cleans up the "DeployablePackages" folder for data older than 30 days on your Dynamics 365 for Finance and Operations, Enterprise Edition machine if you are using the LCS servicing flows.

If you prefer to keep less data, such as 10 days, you can add the following registry key to HKLM:\SOFTWARE\Microsoft\Dynamics\Deployment :



Or copy & paste the below into a *.reg file, and you can add it that way:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Dynamics\Deployment]
"CutoffDaysForCleanup"="10"


See Yammer thread here for Microsoft's comments.

Tuesday, January 2, 2018

How to see when AOS service was started/stopped with PowerShell for AX with 1 line of code.

I often need to see when an AOS was stopped for various reasons, and scanning the event viewer can be a hassle. Running this simple 1-line PowerShell script will give you that information.

You can also use this script as a guide to run other PowerShell scripts to search the event log for specific text.

Get-WinEvent -ErrorAction SilentlyContinue -FilterHashtable @{logname='system'; StartTime=(((get-date).AddDays(-30).Date)); EndTime=(((get-date).AddDays(1).Date)); id=7036} -MaxEvents 10000 | ? {$_.Message -like '*Microsoft Dynamics AX Object Server*'}