Friday, August 19, 2016

Error System.IO.File::Move when using batch process on AX 2012 R3

Problem:

On syntax

System.IO.File::Move(fileName, newFileName);

You get this error when using batch process:

 "System.IO.IOException: The process cannot access the file because it is being used by another process"


Cause:
Possibility
A. Your AOS services is using user which have less security access to folders.
B. You read or access files but not closed yet.


Solution:
A. Add more security access to user who run the AOS services.

B. Closing File

Step-1

Close the files before CodeAccessPermission::revertAssert();

Example:

io              = new TextIO(filenameOp, "r");
io.read();

.....
io.finalized;
io = null;
  
CodeAccessPermission::revertAssert();

Step-2 

Build Generate Increament CIL


Step-3
Close and Open AX.

Tuesday, July 19, 2016

Error when configuring Management Reporter 2012 for Dynamics AX 2012 R3

Problem:

You get error message when config MR 2012:

"An unexpected error occurred while querying the Metadata service"

System.ServiceModel.FaultException`1[Microsoft.Dynamics.Performance.Deployment.DataProvider.AX.AX2012MetadataService.MetadataFault]: An exception of type MetdataException has occurred while performing the operation. (Fault Detail is equal to Microsoft.Dynamics.Performance.Deployment.DataProvider.AX.AX2012MetadataService.BatchFault).

Cause:
You add custom fields to table which is used as Financial Dimension.

e.g. You add custom fields to InventLocation, and use the table as Custom as Financial Dimension.


Solution:

Add relations to fields on the table.
Every additional fields on the table which is used to Financial Dimension must have relations.


Reference:
a. How to add table to be use on Financial Dimension:
https://dynamicsaxinsight.wordpress.com/2014/07/14/ax-2012-add-financial-dimension-for-your-table/

b. Another same problem
https://community.dynamics.com/ax/f/33/t/123925
 
Thank's to David Orr

Friday, April 22, 2016

Get List of Number Sequence in AX 2012 R3

static void Test_NumberSeqTableRef(Args _args)
{
    NumberSequenceTable         _nst;
    NumberSequenceReference     _nsr;
    NumberSequenceDataType      _nsd;
    ;
   
    while select _nst
        order by _nst.NumberSequence 
        join _nsr
            where _nst.RecId == _nsr.NumberSequenceId
        join _nsd
            where _nsd.RecId == _nsr.NumberSequenceDatatype
            && _nst.Txt like 'AAA *'
         
    {
        info(strFmt('%1 ; %2 ; %3 ; %4 ; %5 ; %6',_nst.NumberSequence,_nst.Txt,_nst.Format,_nst.Highest,
        _nsd.referenceLabelForDisplay(), _nsd.referenceModuleLabel() ));
    }       
}

Thursday, April 21, 2016

Class to Create Item Group include Main Account in AX 2012 R3

CreateInventGroup::Create(itemGroupx,itemGroupNamex,inventoryAccx,expenseAccx,revenueAccx,interUnitAccx);

==============

class CreateInventGroup
{
}


public static void Create(
ItemGroupId _itemGroupId,
Name _itemGroupName,
MainAccountNum _inventoryAcc,
MainAccountNum _expenseyAcc,
MainAccountNum _revenueAcc,
MainAccountNum _interUnitAcc,
MainAccountNum _wipAcc=''
)
{
    InventPosting                       _inventPosting;
    InventItemGroup                     _itemGroup0,_itemGroup;
    InventItemGroupForm                 _itemGroupForm;

    InventAccountType                   inventAcctTypeEnum;
    InventPostingItemCode               inventItemCodeEnum;
    container                           conCOAInventory,conCOAExpense,conCOARevenue,conCOAInterunit,conCOAWIP;
    ItemGroupId                         itemGroupx;
    Name                                itemGroupNamex,invttypex;
    MainAccountNum                      inventoryAccx,expenseAccx,revenueAccx,interUnitAccx,wipAccx;
    int                                 i,counterx;
    ;

    itemGroupx                          = _itemGroupId;
    itemGroupNamex                      = _itemGroupName;
    inventoryAccx                       = _inventoryAcc;
    expenseAccx                         = _expenseyAcc;
    revenueAccx                         = _revenueAcc;
    interUnitAccx                       = _interUnitAcc;
    wipAccx                             = _wipAcc;

    conCOAInventory     =  ['Inventory, issue',
                            'Inventory, receipt',
                            'Product receipt',
                            'Production, issue',
                            'Production, picking list',
                            'Production, receipt',
                            'Production, report as finished',
                            'Purchase, inventory receipt',
                            'Sales order, issue',
                            'Order, packing slip'];

    conCOAExpense       =  ['Inventory, loss',
                            'Inventory, profit',
                            'Purchase expenditure for expense',
                            'Purchase expenditure for product',
                            'Sales order, consumption',
                            'Sales, packing slip offset'];

    conCOARevenue       =  ['Sales order, revenue'];

    conCOAInterunit     =  ['Inventory inter-unit payable','Inventory inter-unit receivable'];

    conCOAWIP           = [ 'Production, issue offset',
                            'Production, picking list offset',
                            'Production, receipt offset',
                            'Production, report as finished offset'];

    _itemGroup0 = InventItemGroup::find(itemGroupx);

    if(!_itemGroup0)
    {
        ttsBegin;
        _itemGroup.clear();
        _itemGroup.ItemGroupId     = itemGroupx;
        _itemGroup.Name            = itemGroupNamex;
        _itemGroup.validateWrite();
        _itemGroup.insert();
        ttsCommit;

        if(inventoryAccx)
        {
            for (i=1; i <= conLen(conCOAInventory); i++)
            {
                invttypex = conPeek(conCOAInventory, i);

                ttsBegin;
                _inventPosting.clear();
                _inventPosting.initValue();
                _inventPosting.InventAccountType = str2enum(inventAcctTypeEnum,invttypex);
                _inventPosting.ItemCode = str2enum(inventItemCodeEnum,'Group');
                _inventPosting.ItemRelation = itemGroupx;
                _inventPosting.CustVendCode = TableGroupAll::All;
                _inventPosting.LedgerDimension = DimensionStorage::getDefaultAccountForMainAccountNum(inventoryAccx);
                _inventPosting.validateWrite();
                _inventPosting.insert();
                ttsCommit;
                DIP_CreateInventGroup::CreateUpdateGroupForm(itemGroupx,_inventPosting.LedgerDimension,invttypex);
            }//for
        }// if(inventoryAccx)

        if(expenseAccx)
        {
            for (i=1; i <= conLen(conCOAExpense); i++)
            {
                invttypex = conPeek(conCOAExpense, i);

                ttsBegin;
                _inventPosting.clear();
                _inventPosting.initValue();
                _inventPosting.InventAccountType = str2enum(inventAcctTypeEnum,invttypex);
                _inventPosting.ItemCode = str2enum(inventItemCodeEnum,'Group');
                _inventPosting.ItemRelation = itemGroupx;
                _inventPosting.CustVendCode = TableGroupAll::All;
                _inventPosting.LedgerDimension = DimensionStorage::getDefaultAccountForMainAccountNum(expenseAccx);
                _inventPosting.validateWrite();
                _inventPosting.insert();
                ttsCommit;
                DIP_CreateInventGroup::CreateUpdateGroupForm(itemGroupx,_inventPosting.LedgerDimension,invttypex);
            }//for
        }// if(expenseAccx)

        if(revenueAccx)
        {
            for (i=1; i <= conLen(conCOARevenue); i++)
            {
                invttypex = conPeek(conCOARevenue, i);

                ttsBegin;
                _inventPosting.clear();
                _inventPosting.initValue();
                _inventPosting.InventAccountType = str2enum(inventAcctTypeEnum,invttypex);
                _inventPosting.ItemCode = str2enum(inventItemCodeEnum,'Group');
                _inventPosting.ItemRelation = itemGroupx;
                _inventPosting.CustVendCode = TableGroupAll::All;
                _inventPosting.LedgerDimension = DimensionStorage::getDefaultAccountForMainAccountNum(revenueAccx);
                _inventPosting.validateWrite();
                _inventPosting.insert();
                ttsCommit;
                DIP_CreateInventGroup::CreateUpdateGroupForm(itemGroupx,_inventPosting.LedgerDimension,invttypex);
            }//for
        }// if(revenueAccx)

        if(interUnitAccx)
        {
            for (i=1; i <= conLen(conCOAInterunit); i++)
            {
                invttypex = conPeek(conCOAInterunit, i);

                ttsBegin;
                _inventPosting.clear();
                _inventPosting.initValue();
                _inventPosting.InventAccountType = str2enum(inventAcctTypeEnum,invttypex);
                _inventPosting.ItemCode = str2enum(inventItemCodeEnum,'Group');
                _inventPosting.ItemRelation = itemGroupx;
                _inventPosting.CustVendCode = TableGroupAll::All;
                _inventPosting.LedgerDimension = DimensionStorage::getDefaultAccountForMainAccountNum(interUnitAccx);
                _inventPosting.validateWrite();
                _inventPosting.insert();
                ttsCommit;
                DIP_CreateInventGroup::CreateUpdateGroupForm(itemGroupx,_inventPosting.LedgerDimension,invttypex);
            }//for
        }// if(interUnitAccx)

        if(wipAccx)
        {
            for (i=1; i <= conLen(conCOAWIP); i++)
            {
                invttypex = conPeek(conCOAWIP, i);

                ttsBegin;
                _inventPosting.clear();
                _inventPosting.initValue();
                _inventPosting.InventAccountType = str2enum(inventAcctTypeEnum,invttypex);
                _inventPosting.ItemCode = str2enum(inventItemCodeEnum,'Group');
                _inventPosting.ItemRelation = itemGroupx;
                _inventPosting.CustVendCode = TableGroupAll::All;
                _inventPosting.LedgerDimension = DimensionStorage::getDefaultAccountForMainAccountNum(wipAccx);
                _inventPosting.validateWrite();
                _inventPosting.insert();
                ttsCommit;
                DIP_CreateInventGroup::CreateUpdateGroupForm(itemGroupx,_inventPosting.LedgerDimension,invttypex);
            }//for
        }// if(interUnitAccx)

    } //if(!_itemGroup0)

}


public static void CreateUpdateGroupForm(
ItemGroupId _itemGroupIdx,
LedgerDimensionDefaultAccount _ledgerDimDefaultx,
Name _inventAcctTypex
)
{
    InventItemGroupForm                 _itemGroupForm,_itemGroupForm1;
    InventAccountType                   inventAcctTypeEnum;
    ItemGroupLedgerDimensionGroup       itemGroupDimGroup;
    ;

    select * from _itemGroupForm
      where _itemGroupForm.ItemGroupId == _itemGroupIdx
         &&  _itemGroupForm.InventAccountType == str2enum(inventAcctTypeEnum,_inventAcctTypex);

        switch(_inventAcctTypex)
        {
            Case    'Inventory, issue',
                    'Inventory, receipt',
                    'Inventory, loss',
                    'Inventory, profit',
                    'Inventory inter-unit payable',
                    'Inventory inter-unit receivable':

                itemGroupDimGroup = ItemGroupLedgerDimensionGroup::Inventory;
            break;

            Case    'Production, issue',
                    'Production, picking list',
                    'Production, receipt',
                    'Production, report as finished',
                    'Production, issue offset',
                    'Production, picking list offset',
                    'Production, receipt offset',
                    'Production, report as finished offset':

                itemGroupDimGroup = ItemGroupLedgerDimensionGroup::Production;
            break;

            Case    'Sales order, issue',
                    'Order, packing slip',
                    'Sales order, consumption',
                    'Sales, packing slip offset',
                    'Sales order, revenue':

                itemGroupDimGroup = ItemGroupLedgerDimensionGroup::Sales;
            break;

            Case    'Purchase, inventory receipt',
                    'Product receipt',
                    'Purchase expenditure for expense',
                    'Purchase expenditure for product':

                itemGroupDimGroup = ItemGroupLedgerDimensionGroup::Purchase;
            break;
        }//switch


    if(!_itemGroupForm)
    {
        ttsBegin;
        _itemGroupForm.clear();
        _itemGroupForm.initValue();
        _itemGroupForm.InventAccountType = str2enum(inventAcctTypeEnum,_inventAcctTypex);
        _itemGroupForm.ItemGroupId = _itemGroupIdx;
        _itemGroupForm.LedgerDimension = _ledgerDimDefaultx;
        _itemGroupForm.LedgerDimensionGroup = itemGroupDimGroup;
        _itemGroupForm.validateWrite();
        _itemGroupForm.insert();
        ttsCommit;
    }
    else
    {
        while select forupdate _itemGroupForm1
          where _itemGroupForm1.ItemGroupId == _itemGroupIdx
             &&  _itemGroupForm1.InventAccountType == str2enum(inventAcctTypeEnum,_inventAcctTypex)
        {
            ttsBegin;
            _itemGroupForm1.LedgerDimension = _ledgerDimDefaultx;
            _itemGroupForm1.LedgerDimensionGroup = itemGroupDimGroup;
            _itemGroupForm1.validateWrite();
            _itemGroupForm1.update();
            ttsCommit;
        }
    }
}



Wednesday, January 6, 2016

Can not rename InventTable in AX 2012 R3

"You cannot rename the record because the table (InventTable) has a distribution type Same as parent distribution and not No distribution."

Solution:

Step-1
Menu: Retail > Setup > Parameters > Retail scheduler parameters


Step-2

 Menu: Retail > Setup > Retail scheduler > Scheduler subjob




Remove and Add it back.




Wednesday, December 23, 2015

Ms Excel macro to create txt file

Macro to create txt file (flat file). You could change separator as you need. 

Txt creator

Here is the code:

Sub CreateTXT()

    Dim rCell As Range
    Dim rRow As Range
    Dim sOutput As String
    Dim sFname As String, lFnum As Long
      
   
    'Open a text file to write


     sFname = "C:\AX\" & ActiveSheet.Name & ".txt"
    lFnum = FreeFile
       
    Open sFname For Output As lFnum
    'Loop through the rows'
        For Each rRow In ActiveSheet.UsedRange.Rows
        'Loop through the cells in the rows'
        For Each rCell In rRow.Cells
            sOutput = sOutput & rCell.Value & ";"  'SEPARATOR !!!
        Next rCell
         'remove the last comma'
        sOutput = Left(sOutput, Len(sOutput) - 1)
      
        'write to the file and reinitialize the variables'
        Print #lFnum, sOutput
        sOutput = ""
     Next rRow
  
    'Close the file'
    Close lFnum
       
   
End Sub