Quantcast
Channel: Dynamics Ax – Shashi's Ax.Net Space
Viewing all 56 articles
Browse latest View live

AX2012 – Compare model. When you put in hotfixes, updates and want to do less – Part 1

$
0
0
via Tamás Mészáros

So you got updated Model(s) or hotfix(es) and need to make sure your ISV or VAR or CUS / USR layer code has been merged.

Lets see what your options are:

  1. Create a project for each model and then compare then to the upper layers for changes.
    — You spend a lot of time giving yourself carpal syndrome
  2. Auto code upgrade
    — It only manages hotfixes. The code that needs to be manually reviewed can be overwhelming? (someone please correct me on that)
  3. You write some script to find out how to do this
  4. Magic beans
    — You don’t get them

Ok, so I wrote some SQL scripts to do this, however it was getting too complex for me and I knew I could do it faster with in memory processing with C#. Although I can argue with myself that SQL can do a better job with this. However, I went to the path of C#

Tables used:

  1. SysElementType – This stores what a node in the AOT is classified as. E.g. TableInstance, ClassInstanceMethod, BaseEnum. This is purely to translate an integer to a human readable value.
  2. SysModelElement – This is where the definition of each object is. So every node in the AOT is one record here. This record also links it to the Parent Element. So a record which is the table field, will have its parent element to the Table itself. A parent element can have another parent element too, e.g. a form element inside a group
  3. SysModelElementData – This is where the code for the SysModelElement is stored. And it it stored for each Model (not layer). Moment I override the code in the USR layer for the SalesFormLetter classdeclaration in Ax, it will create a record in this table with the new code. So use it as a caution, if you ever query this table, be careful because you could be transferring a “lot” of data across the wire

Combining SysModelElementData, i can find what all other models use the same element. Then link it up to sysModelElement and find more information about the AOT object that has changed.

Armed with this knowledge I went and created  C# console application

The project currently compares models. So if you want to know what has affected the VAR and USR layer models with the addition of a particular SYP layer model, then you send the list of SYP model id’s and then the list of VAR and USR layer models as a csv string. This does a fast compare and outputs what objects you need to look at.

The shortcomings / bugs of this so far:

  1. Security, menu items dont get compared because of the way this is stored
  2. Currently you need to compare models. I would like to say i need to know what objects are affected by these SYP models and then get a list of objects on all the higher layers
  3. Need to create a library instead of a console project

This project is posted on GitHub: https://github.com/shashisadasivan/AxCodeCompare.git


Filed under: Ax 2012, Dynamics Ax Tagged: AX2012, AxAdministration

AX 2012 Install Model – A Checklist

$
0
0

This is a checklist I follow to install Models Provided for a installed site

  1. Stop the AOS
  2. Backup the Database
  3. Install models (follow guidelines, you may be told to use the overwrite option)
  4. Merge Code (optional)
    1. Start AOS
    2. Merge Code
    3. Stop AOS
  5. Compile X++
    1. Option 1 – AxBuild.exe (RU7 and Onwards)
      1. Make sure AOS is turned off
    2. Option 2
      1. Start AOS
      2. Open Ax Client
      3. Compile
      4. Stop AOS
  6. Compile CIL
    1. Start AOS
    2. Open Ax Client
    3. Run Full CIL Compile
  7. Restart AOS
  8. Synchronize database
  9. Restart AOS

If you do restore a Live database over the TEST database, make sure to transfer the parameters as well as reset the SYSSQMSettings.GlobalGUID


Filed under: Ax 2012, Dynamics Ax Tagged: ax 2012, AX2012, AxAdministration

AX2012 Terminating a compile worker

$
0
0
Moral of the story: NEVER KILL A COMPILER WORKER WINDOW EVER

There was a time I “accidentally” closed a compiler widow of a 10 worker process in the 2nd run.
Even though the main window notified that a worker terminated without any reason code, it still continued the process and reported that the compile was successful. Including an error log with a clean compile log (except for warnings, who looks at warnings!!! ;) )
The next part which is compile the CIL went a bit weird.

The CIL compiler would start and AX stared at me for about a minute (as if its doing something, even the processors reported a good 98% usage for the AOS process) and then the AX screen came back to life.

The weirdness continues

  • It didn’t report anything.
  • There was no infolog to tell me that the services were generated, or the CIL compiler had failed.
  • There was nothing in the event log.
  • I even did a AOS restart with the deletion of the xppil folder, and yet I got the same result.
  • There was no CIL compiler log generated either.

So turns out (whatever happens inside the engine) that you should NEVER KILL A COMPILER WORKER WINDOW EVER !

via arkansas-investigations.com

Filed under: Ax 2012, Dynamics Ax Tagged: AX2012, Compiler, Dynamics Ax

AX2012 – Compare model. When you put in hotfixes, updates and want to do less – Part 1

$
0
0
via Tamás Mészáros

So you got updated Model(s) or hotfix(es) and need to make sure your ISV or VAR or CUS / USR layer code has been merged.

Lets see what your options are:

  1. Create a project for each model and then compare then to the upper layers for changes.
    — You spend a lot of time giving yourself carpal syndrome
  2. Auto code upgrade
    — It only manages hotfixes. The code that needs to be manually reviewed can be overwhelming? (someone please correct me on that)
  3. You write some script to find out how to do this
  4. Magic beans
    — You don’t get them

Ok, so I wrote some SQL scripts to do this, however it was getting too complex for me and I knew I could do it faster with in memory processing with C#. Although I can argue with myself that SQL can do a better job with this. However, I went to the path of C#

Tables used:

  1. SysElementType – This stores what a node in the AOT is classified as. E.g. TableInstance, ClassInstanceMethod, BaseEnum. This is purely to translate an integer to a human readable value.
  2. SysModelElement – This is where the definition of each object is. So every node in the AOT is one record here. This record also links it to the Parent Element. So a record which is the table field, will have its parent element to the Table itself. A parent element can have another parent element too, e.g. a form element inside a group
  3. SysModelElementData – This is where the code for the SysModelElement is stored. And it it stored for each Model (not layer). Moment I override the code in the USR layer for the SalesFormLetter classdeclaration in Ax, it will create a record in this table with the new code. So use it as a caution, if you ever query this table, be careful because you could be transferring a “lot” of data across the wire

Combining SysModelElementData, i can find what all other models use the same element. Then link it up to sysModelElement and find more information about the AOT object that has changed.

Armed with this knowledge I went and created  C# console application

The project currently compares models. So if you want to know what has affected the VAR and USR layer models with the addition of a particular SYP layer model, then you send the list of SYP model id’s and then the list of VAR and USR layer models as a csv string. This does a fast compare and outputs what objects you need to look at.

The shortcomings / bugs of this so far:

  1. Security, menu items dont get compared because of the way this is stored
  2. Currently you need to compare models. I would like to say i need to know what objects are affected by these SYP models and then get a list of objects on all the higher layers
  3. Need to create a library instead of a console project

This project is posted on GitHub: https://github.com/shashisadasivan/AxCodeCompare.git


Filed under: Ax 2012, Dynamics Ax Tagged: AX2012, AxAdministration

AX 2012 Install Model – A Checklist

$
0
0

This is a checklist I follow to install Models Provided for a installed site

  1. Stop the AOS
  2. Backup the Database
  3. Install models (follow guidelines, you may be told to use the overwrite option)
  4. Merge Code (optional)
    1. Start AOS
    2. Merge Code
    3. Stop AOS
  5. Compile X++
    1. Option 1 – AxBuild.exe (RU7 and Onwards)
      1. Make sure AOS is turned off
    2. Option 2
      1. Start AOS
      2. Open Ax Client
      3. Compile
      4. Stop AOS
  6. Compile CIL
    1. Start AOS
    2. Open Ax Client
    3. Run Full CIL Compile
  7. Restart AOS
  8. Synchronize database
  9. Restart AOS

If you do restore a Live database over the TEST database, make sure to transfer the parameters as well as reset the SYSSQMSettings.GlobalGUID


Filed under: Ax 2012, Dynamics Ax Tagged: ax 2012, AX2012, AxAdministration

X++ and Ax7 Whats Changed

$
0
0

A lot of changes have taken place in the X++ language and to align it close to the C# model which is where we want to be. There is no longer any p-code compilation, everything is run from the CIL.

This my compilation of what has changed and some examples for them as well.

Editing Experience: Visual studio interface only. Finally a more structured way of viewing code.

Declare anywhere

for(int i = 0; i< 10; i++)
{
  // variable i can only be referenced here
}
// Try to retrieve i here and you will receive a compile error

The var keyword: :star:

</pre>
<pre>var counter = 0;
var custTable = salesTable.custTable();

Static constructor and fields: Static member variables Static constructors: TypeNew

class AClass
{
    static string staticString;
    static void TypeNew()
    {
        AClass::staticString = "Static World!";
    }
}

Macros: As i suspected, try avoiding these guys. Will be deprecated in later releases (my view) const (constant) and readonly:

class Square
{
    public const int Sides = 4; // this value cannot be changed
    readonly real _length = 10; // this is a default

    void new(real length)
    {
        this._length = length; // readonly can be changed in constructors only
    }
}
Field Access: :star:
Field access was only protected in Ax (no questions asked, and nothing else you can do about it)
Now: if you havent specified the access they are still protected, but you can specify public, or private
class MyVariables
{
    int myInt;
    protected int myInt2;
    public string Name;
    private real _qty;
}
class MyVariables2 : MyVariables
{
    void WhatCanIDo()
    {
        myInt++;
        myInt2 = myInt + 10;
        Name = "My New World!";
        _qty = 100; // Compilation error
    }
}

class AccessVariables
{
    void WhatCanIDo()
    {
        var myVariables = new MyVariables();
        myVariables.myInt = 10; // Error
        myVariables.myInt2 = 100; // Error
        myVariables.Name = "Hello";
        myVariables._qty = 100; // Error
    }
}

Access variables by reference
Lets the above example

class MyVariables
{
    int myInt;
    public string Name;

    public void AccessVarisables()
    {
        this.myInt = 5;// This references to itself,and works with intellisense:)
        this.Name = "Hello World!";
    }
}
class Access
{
    public AccessVariables()
    {
        var myVars = new MyVariables();
        myVars.Name = "Hello New world!"; // Name is accessed via the class object,no more Parm methods required;
    }
}

try / catch / Finally: :star:

try
{

}
catch(Exception::Error)
{
    // you can add multiple catch types as normal
}
finally
{
   // this code always gets called. So you can do things like close file handles
}

using statement:⭐
Using is here, this is very neat. It destroys the object and the object only exists within the context of the using. Object in the using should implement IDisposable, so all / most of the Streams are an example or webRequests.

using(var sw = new System.IO.StreamWriter("file.txt"))
{
     sw.writeLine("Hello World!");
}

Implement .Net Classes:
Classes in X++ can implement the C# classes:) , so your X++ class can implement IDisposable

Extension Methods:

There are very similar to C# extensions, except the convention is to end the class with _Extension and not Extension

static class HelloWorld_Extensions // Convention is to have _Extension
{
// This adds a method to the salesTable called SalesString returning a string
// salesTable.SalesString()
public static str SalesString(SalesTable salesTable)
{
return salesTable.SalesId + "-" + salesTable.CustName();
}

// you can add more extensions here targetting different types
}

Declarative Eventing (Methods and objects):

Ax 2012 gave us the ability to add events to methods. This is still the same, i.e. events still exist, exept they are called declaratively (i.e. in code and no clicks).

Although, the way to access arguments is still not to my liking and even though it seperates code out a lot, any errors are at runtime only, which can be very “hard” to manage

Casting is standard now:

// Planet class is implemented by class Earth.
var Earth = new Planet(); // this is incorrect, used to work before

Filed under: AX7, Dynamics Ax, X++

AX 2012 License generator UI

$
0
0

So i had created a UI for the license generator.

To create a license in 2012 this was the command:

axutil genlicense /file:c:\licenses\MyLicense.txt /certificatepath:c:\certificates\MyCertificate.pfx /licenseCode:MyModule /customer:MyCustomer /serialnumber:1231232123 /password:MySecretPassword123 /expirationdate:12/30/2018 /usercount:5

However, having the password and certificate path information available wasnt exactly a good idea at that time (and probably is still relevant. Why would you want to distribute those two together no?)

So came the the License generator, with the password hard coded and everything else seemingly invisible to the person punching the licenses without having someone with knowledge of the axutil and more importantly

What is this black box ? and why cant I just click somewhere

Moving forward a few years later and opening up the code out, (yes the password has been taken out of the code). Its now stored as well, although not very secure, but enough to keep prying eyes out for a bit. (this means rooms for improvement)

The code is published at GitHub under AxLicenseGenerator (See the readme in that link)

Or you can Download Ax License Generator 1.1

There is lots more information there, or message me if you need more information.

Happy Licensing

LicGenerator_V1.1
License Generator v 1.1

Filed under: .Net, Ax 2012, Dynamics Ax

SystemSequences Update

$
0
0

If you ever get a error where the RecId being inserted into the table already exists then the SystemSequences table is to be blamed for this

In some of my previous blog posts, i update the system sequence table’s NextVal record, which determines the RecId to be given. However, this is tricky.

  1. Update in SQL
    • Stop the AOS
    • Update the NextVal recod in the SystemSequences Table
    • Start the AOS
  2. Write a job
static void SetNextRecId(Args _args)
{
    SystemSequences seq;
    ttsBegin;
    select firstonly forupdate crosscompany seq
        where seq.tabId == 123456; // use the table id here or tablenum()
    seq.skipTTSCheck(true);
    seq.skipDatabaseLog(true);
    seq.selectForUpdate(true);
    seq.nextVal = 5637123456 + 1; // enter the last recId for the table
    seq.update();
    ttsCommit;
}

You may need to run this job and restart the AX client only if the just the above doesn’t work

static void sab_recIdSequenceFix(Args _args)
{
    SystemSequence systemSequence = new systemSequence();
    Tableid tableId = 123456; // use the table id or tablenum() here

    systemSequence.suspendRecIds(tableId);
    systemSequence.suspendTransIds(tableId);
    systemSequence.flushValues(tableId);
    systemSequence.removeRecIdSuspension(tableId);
    systemSequence.removeTransIdSuspension(tableId);
}

Filed under: Ax 2009, Ax 2012, Dynamics Ax, X++ Tagged: Ax 2009, AX2012, Dynamics Ax, x++

[AX2012] Get Email for Customer / Vendor (with specific roles)

$
0
0

To get an email address for a Customer or vendor, you can use the following statement

static void DEL_SS_emailStmtjob(Args _args)
{
CustTable cust; //Replace with vendTable for Vendors
DirPartyLocation dirPartyLocation;
LogisticsElectronicAddress elecAddress;
LogisticsElectronicAddressRole elecAddressRole;
LogisticsLocationRole locRole;
select firstOnly cust
where cust.AccountNum == '‪‪‪Cust-001';
while select DirPartyLocation
where dirPartyLocation.party == cust.Party
{
while select elecAddress
where elecAddress.Location == dirPartyLocation.Location
&& elecAddress.Type == LogisticsElectronicAddressMethodType::Email
{
while select elecAddressRole
where elecAddressRole.ElectronicAddress == elecAddress.RecId
join locRole
where locRole.RecId == elecAddressRole.LocationRole
{
info(strFmt("%1 - %2", elecAddress.Locator, locRole.Name));
}
}
}
}


Filed under: Dynamics Ax

[D365] Operations Financial Reporter – Cannot open

$
0
0

Financial reporter “Yet another post if this doesnt open up”
If you get a message from the click once installer saying : “Your security settings do not allow this application to be run on your computer”

Start with running this from IE. Chrome gives some other issues
1. Add the website to your trusted sites (via internet options > Security > trusted websites > Sites and add it over there)
2. Edit the registry editor (Start > regedit OR Start + r > regedit.exe)
3. Navigate to \HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT.NETFramework\Security\TrustManager\PromptingLevel
4. Change the value for TrustedSites from Disabled to Enabled
(if this is your own system and you work on multi[ple environments, then probably change the value of Internet as well from Disabled to Enabled)
5. Save regedit and restart IE.

Note: Edge / IE12 has better chances of running the clickonce than chrome

Source: https://msdn.microsoft.com/en-us/library/ee308453.aspx

D365 FO EDMX / OData trimmer – Make your metadata smaller

$
0
0

Creating a .Net application with the OData metadata from your D365 application can generate a large file

A typical metadata file (edmx) retrieved from https://<d365url>/data/$metadata will return a file of almost 17MB. Turn that into a c# file using the T4 templates and the C# source file is almost 64MB.

After spending some time trying to reduce the EDMX file to only the entities I require (and a lot of nagging by my friend) I created a way to remove the excess entities from here. Result is a smaller EDMX file, and a more lightweight .Net application for you.

Reference this Trimmed EDMX file in your T4 template

The project and instructions can be found at my Github project EDMXTrimmer: https://github.com/shashisadasivan/EDMXTrimmer

 

[D365] Fin Ops Dev tools Add ins – location of VS extension folder

$
0
0

When creating Visual studio Tools addins for D365 Fin ops you would need to copy it into the extension folder. This folder is most probably different on every machine.

To get the folder Open Regedit and navigate to: HKCU:\SOFTWARE\Microsoft\VisualStudio\14.0\ExtensionManager\EnabledExtensions

This stores the folder under the property DynamicsRainer*

Store your addin over here.

I have a powershell script that copies all the dll’s into that folder

[D365] Fin ops Visual Studio Addins

$
0
0

D365 & Visual studio gives you the ability to create your own Visual studio Add In for D365 development. The idea for me to create the add-in was to reduce the number of keystrokes and especially moving forward and backwards between the AOT and the code editor. There are quite a few “enhancements” i have added that certainly makes my development life a bit easier.

The Add-in however only works from the Object designer instead of the AOT nodes, which is most of the times a good thing especially when you are searching for code via the code editor.

I will be following up more on the add-ins in future posts.

Checkout the Add-in SSD365VSAddIn

 

Updating SQL intellisense

$
0
0

So you added a new table / field via D365 Finops and synchronised the database.
To get the intellisense to pick those new objects you might be restarting SSMS ?

Instead you could just be refreshing the intellisense OR in other words Refresh intellisense’s local cache

  1. Create a new query window and link it to your database
  2. Click on Edit > Intellisense > Refresh local cache (Ctrl + Shift + R)

You will now have the new objects.

Enjoy !

D365 Finance – Data entities – Import images (document handling)

$
0
0

To import images in D365 can be a bit tricky, if not painstaking. If you look at the previous post for Exporting Images, we had downloaded a package which contained an excel file and a folder with the images. It also included 2 xml files.

Importing data will pretty much be done the same way using a similar zip file which includes the 2 xml files as well PackageHeader.xml and Manifest.xml . These files specify the mapping between the excel and staging table and the entity and name of the excel file.
So to keep it simple, follow the Previous post and export the entity, and download the zip file.

Then you can run a powershell script which will update the filename, copy them across to a folder and rename them.

You may also want to follow this post from Munib Ahmand on importing attachments

Create your Excel file
Get the excel file and clear out the data from there. Then fill it up except for the columns FILETYPE, ORIGINALFILENAME
However, put the full path of the file into the column AttachmentFileName i.e. something like C:\myImages\MyProducts\T0001\TheProductImage1.jpg
Your excel file should now look something like this:
undefined

Run the script
Ok, so the time has come to run the script.
1. Create a new folder anywhere and copy the 2 xml files Manifest.xml and PackageHeader.xml in to the folder
2. Download the following powershell script
3. Open powershell and navigate to the folder where the above script was downloaded
4. Open the excel file that you have and find the following fields AttachmentFileName, FileType, OriginalFileName
In my case
FileType = 7
OriginalFileName = 11
AttachmentFileName = 13
Get the column number starting from 1 for these and close the excel file
5. Run the following command from powershell
PS C:\Temp\DM_Demo> .\FileUpload_ExcelResourceCreator.ps1 -ExcelFilePath “C:\Temp\DM_Demo\Import\Released product document attachments.xlsx" -TargetFolderPath C:\Temp\DM_Demo\Import\DMDemoImport -TargetEntity "Released product document attachments" -ColumnAttachmentFileName 11 -ColumnAttachmentFileType 7 -ColumnAttachmentFilePath 13
This will create a new excel file in the Target folder and update the values inside it . It will also copy the files mentioned in the excel file, rename them to the guid value assosicated in the excel file into the Resources/<entity name> folder
6. Navigate to the target folder (You have to go into the folder)
Select all the files and Zip them

Import the Images / attachments
1. In D365 navigate to Data management
2. Create a new Import Project
3. Select “Add File” and clieck “Upload and add”
Choose your zip file and click “Close”
Because your zip file contains the information about the entities it will add the entities to the project.
4. Click “Import” and your attachment / image will be against the record


What does the Script do?
The script takes the file name from the excel file, and replaces it with a GUID. The file is then copied to the target forlder under resources and renamed to the same GUID. The script also copies the file name and the type of the file (Jpg, png, txt, xlxs, etc) and places it in the excel file


Visual studio – Copy all from Find Symbol Results

$
0
0

can-i-copy-multiple-rows-from-the-visual-studio-find-symbol-results-window

https://stackoverflow.com/questions/1173808/can-i-copy-multiple-rows-from-the-visual-studio-find-symbol-results-window

Sometimes it is probably useful to copy all the data from the Symbol results window in Visual studio. Either to process it manually or to run some analysis on it (Or whatever reason you fancy). Unfortunately Visual studio only allows you to copy one result at a time from that window which doesnt make it very friendly. I had over 600 results 😦

Bring in AutoHotKey ! This is an extremely powerful scripting language. It runs off keyboard shortcuts, so you can run this from where your cursor is pointed at.
For my scenario, i managed to make it run with Ctrl + j and it goes through all the lines so quickly that VS doesnt skip to the source reference file.
Once installed, run it in the same context as Visual studio i.e. is VS is running as an administrator then run the script as an administrator as well (So that VS doesnt capture the hotkeys and keep it to itself)

https://github.com/shashisadasivan/MyScripts/blob/master/Misc/Visual%20Studio/VSCopySymbolResult.ahk
Viewing all 56 articles
Browse latest View live




Latest Images