Wednesday, May 28, 2014

Import HRM Positions from Excel through X++

You can use different options to import data into Dynamics AX 2012 specially the subject line entity (Positions). Data import/export framework would be the best option to import it, you can also use excel addins for this purpose. However, due to large number of tables involved in few import process it might be difficult to judge right tables and their sequence.

You can also use X++ code to import data into AX either from CSV file or from Excel file. The following job in X++ may help you in importing positions from excel file.

static void ImportHRPosition(Args _args)
    SysExcelApplication     application;
    SysExcelWorkbooks       workbooks;
    SysExcelWorkbook        workbook;
    SysExcelWorksheets      worksheets;
    SysExcelWorksheet       worksheet;
    SysExcelCells           cells;
    COMVariantType          type;
    OMOperatingUnit         OMOperatingUnit;
    int                     row=1;

    Name                                name;
    FileName                            filename;
    HcmPosition                         HcmPosition;
    HcmPositionDetail                   HcmPositionDetail;
    HcmPositionWorkerAssignment         HcmPositionWorkerAssignment;
    HcmPositionDuration                 HcmPositionDuration;
    str                                 job;
    OMOperatingUnitNumber               department;

    application = SysExcelApplication::construct();
    workbooks   = application.workbooks();

    filename = "C:\\import\\HRPosition.xlsx";

    catch (Exception::Error)
        throw error("File cannot be opened.");
    workbook    = workbooks.item(1);
    worksheets  = workbook.worksheets();
    worksheet   = worksheets.itemFromNum(1);
    cells       = worksheet.cells();

        HcmPosition.PositionId  = cells.item(row, 1).value().bStr();
        department              = cells.item(row, 2).value().bStr();
        job                     = cells.item(row, 3).value().bStr();
        select firstOnly OMOperatingUnit where OMOperatingUnit.OMOperatingUnitNumber == department;
            HcmPositionDetail.Department    = OMOperatingUnit.RecId;
            HcmPositionDetail.Job           = HcmJob::findByJob(job).RecId;
            HcmPositionDetail.Position      = HcmPosition.RecId;

            HcmPositionDetail.Title         = HcmTitle::findByTitle(HcmJobDetail::findByJob(HcmPositionDetail.Job).Description).RecId;
            HcmPositionDetail.Description   = cells.item(row, 4).value().bStr();
            HcmPositionDetail.ValidFrom     = DateTimeUtil::newDateTime(cells.item(row, 5).value().date(),timeNow());
            HcmPositionDetail.ValidTo       = DateTimeUtil::maxValue();
            HcmPositionWorkerAssignment.ValidFrom   = DateTimeUtil::newDateTime(cells.item(row, 5).value().date(),timeNow());
            HcmPositionWorkerAssignment.ValidTo     = DateTimeUtil::maxValue();
            HcmPositionWorkerAssignment.Position    = HcmPosition.RecId;
            HcmPositionWorkerAssignment.Worker      = HcmWorker::findByPersonnelNumber(cells.item(row, 6).value().bStr()).RecId;
            HcmPositionDuration.Position    = HcmPosition.RecId;
            HcmPositionDuration.ValidFrom   = HcmPositionWorkerAssignment.ValidFrom;
            HcmPositionDuration.ValidTo     = DateTimeUtil::maxValue();

            type = cells.item(row+1, 1).value().variantType();           
    while (type != COMVariantType::VT_EMPTY);

SysDictTable object not intialized - Data Import/Export Framework

I got the following error while importing Employee Master data using Data Import/Export Framework (from staging to target entities).

After doing some debugging I found there was a table “RetailStaffTable” in Emloyee Entity structure but the Retail configuration key was turned off or Retail components were not installed.  
I ended up deleting the record from the DMFTargetEntityHierarchy table. (Alt+F9 to delete from table browser). I reran the process and it went fine.

Restrict non-admin users to open multiple sessions in AX

Few times client asked to restrict their users to not open AX sessions multiple times. As It may impact on performance somehow. The following code snipet can do this job for you.

NOTE: Please take backup of your application before copying code

Copy Paste the Following Code in startupPost method of info class in AOT

void startupPost()
   // To restrict user login form second login
   xSession session;
   SysClientSessions SysClientSessions;
   UserId currentUserId;
   int counter;

   currentUserId = curUserId();

   if(currentUserId!="Admin")// Allow Admin User to login multiple time
      while select SysClientSessions
         where SysClientSessions.userId == currentUserId
         &&     SysClientSessions.Status == 1 // 1 : Login 0 : Logout
         session = new xSession(SysClientSessions.SessionId, true);
         if (session && session.userId())

      if (counter >= 2)
         Box::stop("Already Logged-in : The same user id can't log in twice.");

Thursday, May 22, 2014

AX 2012 - Compile and CIL Generation errors

Someone may come across the following compilation errrors in classes while compiling the application;


When I dig into these errors it was related to Microsoft.Dynamics.AX.Framework.Analytics.DLL that is installed with Reporting Extensions.

Install the SQL 2008 R2 Analysis Managment Objects (my running version of SQL) on the same machine as the AX Client (in my scenario, the AOS server) . Then recompile!

Sunday, May 18, 2014

AX 2012: Forms and Tables methods call sequence

Many a times we came across the point that where should we write code either it would be in init() of a form or in datasource init() method. And which method will be called first and where you can actually retireve record and what would be best way to accomplish few basic requirements without impacting the performance.

For all above reasons I found an interesting link and thought it would be worth sharing here.

Access denied; Copying DLL into Windows Server 2012

Installing .DLL file into GAC folder of windows is just a drag & drop procedure and it always work. However, things can be annoyed if this simple thing does not work as it happened with me and I was having the following access denied error even I was logged in with Administrator.

There is another way to install .DLL file through power shell and following commands can be used to install and remove .DLL from GAC folder. You can also have a look on techNet article for more details.

Add a DLL to the GAC

1. Run the Power Shell console as Administrator.
2. Enter the following PowerShell

Set-location "c:\Folder Path"            
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")            
$publish = New-Object System.EnterpriseServices.Internal.Publish            
$publish.GacInstall("c:\Folder Path\DLL.dll")            

Remove DLL to the GAC

1. Run the PowerShell console as Administrator.
2. Enter the following Power Shell

Set-location "c:\Folder Path"            
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")            
$publish = New-Object System.EnterpriseServices.Internal.Publish            
$publish.GacRemove("c:\Folder Path\DLL.dll")            

Wednesday, May 14, 2014

Dynamics AX 2012 R3 is released!

AX 2012: How to retrieve the license information through X++

Recently I came across the requirement to retrieve the licence information from the system to use it for some purpose.

Here is the sample to job to get license information.

static void getLicenseValue(Args _args)
    str licVal;
    licVal = xSysConfig::find(ConfigType::SerialNo, 0).Value;
    info(strFmt("%1", licVal));