9 Ağustos 2017 Çarşamba

AX 2012 - Add filter for one dimension for a query's financial dimension

If you try to this with add tables you'll see you have to add lots of table to query. There is a class which do this for you DimensionProvider with AX 2012:

DimensionProvider           dimProvider = new DimensionProvider();


        dimProvider.addAttributeRangeToQuery(element.query(),element.query().dataSourceNo(1).name(),
       FieldStr(MyTable,DefaultDimension),
        DimensionComponent::DimensionAttribute,
        OMOperatingUnit::find(depRecId,OMOperatingUnitType::OMDepartment).OMOperatingUnitNumber,
            "Department",true);

BTW if you get an error like Unknown type: RefRecId it would be about EDT of your table. In my case they used RefRecId EDT instead of DimensionDefault EDT with DefaultDimension field. In your case it would be other than RefRecId. There is a bug like this with original AX table HcmEmployment.

8 Ağustos 2017 Salı

AX 2012 - Check if period closed

Ledger:

FiscalCalendars::checkModuleIsOpen(SysModule::Ledger, LedgerJournalTrans.TransDate,FiscalCalendars::findPeriodByPeriodCodeDate(Ledger::fiscalCalendar(CompanyInfo::find().RecId),LedgerJournalTable.ETGTransDate),false)

Sales:

FiscalCalendars::checkModuleIsOpen(SysModule::Sales, CustInvoiceJour.InvoiceDate,FiscalCalendars::findPeriodByPeriodCodeDate(Ledger::fiscalCalendar(CompanyInfo::find().RecId),CustInvoiceJour.InvoiceDate),false)

Invent closing:

InventClosing::findClosingDate(endmth(InventJournalTrans.TransDate))

2 Ağustos 2017 Çarşamba

AX 2012 - Compile Error about Security Development Tool

Security Development Tool  is a great tool for security issues. But sometimes it would be a trouble. If you get this error you have to know reason is that tool:

Error executing code: SysSecurityRecorder_**** object does not have method 'MenuItemInvoked'.

I just found a blog which is written in french and I translated into english with Google translate (Unfortunately Google translate is terrible with turkish translates). There are two methods advised there succeeded with me:

Way #1: Delete AOD files per client computer.

Way #2: Just run this code at AX DB:

UPDATE SYSSQMSETTINGS SET GLOBALGUID = '{00000000-0000-0000-0000-000000000000}'

7 Temmuz 2017 Cuma

AX 2012 - Send data from server class to form with TempDB

If you try to send data from server class to form with TempDB by parameter you'll see no data will be came. You may select In Memory table or use linkPhysicalTableInstance method to link two TempDB table:

Class:

public static server void populateData(MyTempTable _tmp)
{
MyTempTable tmp;
...
...
tmp.linkPhysicalTableInstance(_tmp);
...
...
return;
}

Form:


MyClass::populateData(MyTempTable);
MyTempTable_DS.research();
MyTempTable_DS.refresh();

4 Ocak 2017 Çarşamba

AXAPTA - Synchronize tables

That code works on common situation my colleauge found from web (don't know the source):

    Dictionary              dict;
    int                     idx, lastIdx, totalTables;
    TableId                 tableId;
    Application             application;
    SysOperationProgress    progress;
    StackBase               errorStack;
    ErrorTxt                errorTxt;
    ;

    application = new Application();
    dict = new Dictionary();
    totalTables = dict.tableCnt();
    progress = new SysOperationProgress();
    progress.setTotal(totalTables);
    progress.setCaption("@SYS90206");
    errorStack = new StackBase(Types::String);

    lastIdx = 3000;
    try
    {
        for (idx = lastIdx+1; idx <= totalTables; idx++)
        {
            tableId = dict.tableCnt2Id(idx);
            progress.setText(dict.tableName(tableId));

            lastIdx = idx;
            application.dbSynchronize(tableId, false, true, false);
            progress.incCount();
        }
    }
    catch (Exception::Error)
    {
        errorTxt = strFmt("Error on table: '%1' (%2) ", tableId, dict.tableName(tableId));
        errorStack.push(errorTxt);
        retry;
    }

    setPrefix("@SYS86407");
    errorTxt = errorStack.pop();
    while (errorTxt)
    {
        error(errorTxt);
        errorTxt = errorStack.pop();
    }

12 Aralık 2016 Pazartesi

AX 2012 - Run Questionnaires with X++ and get Answer table answer Id

There are lots of pages about questionnaires at the web. So I won't tell anything about using and run
questionnaires from menus.

KMCollection - Questionnaire records table. kmCollectionId is key field.

KMVirtualNetworkAnswerTable - Answers table.  kmVirtualNetworkAnswerTableId is key field. Result is saved at evaluation field as failed/passed or empty.
KMVirtualNetworkAnswerLine - Answers lines table.

Run Questionnaire with code:
  
KMQuestionnaireRun       o = new CrsKMQuestionnaireRun();
 

o.set(KMQuestionnaireRunMode::All,myKMCollectionId, DirPersonUser::find(curUserId()).party());
o.run();
Run Answer form with code:

KMVirtualNetworkAnswerTable answerTable;
Args                        args = new Args();
RecId                       recId = DirPersonUser::find(curUserId()).party();
 

select firstOnly answerTable
        where answerTable.kmVirtualNetworkAnswerTableId == this.AnswerId;

args.record(answerTable);args.caller(o);
    new MenuFunction(menuItemDisplayStr(KMKnowledgeCollectorUserResults), MenuItemType::Display).run(args);


I extended KMQuestionnaireRun_Win32 class for save KMVirtualNetworkAnswerTable's ID field to my table at my caller form:

class myKMQuestionnaireRun extends KMQuestionnaireRun_Win32
{
    recId   myRecId;
}


I added a parm method for save caller table RecId:

RecId  parmMyRecId(RecId _recId = myRecId)
{
    myRecId =_recId;
    return myRecId;
}


Derived end method of MQuestionnaireRun_Win32:

public void end(KMVirtualNetworkAnswerTableId _kmVirtualNetworkAnswerTableId)
{
    myCallerTable    tbl; //Questionnaries formunu çağıran tablo

    super(_kmVirtualNetworkAnswerTableId);
    if (_kmVirtualNetworkAnswerTableId == "")
        return;
  

      ttsBegin;
        update_recordSet tbl setting AnswerId = _kmVirtualNetworkAnswerTableId
            where tbl.RecId == myRecId;
        ttsCommit;
}

 
And call from my table:
...
myKMQuestionnaireRun       o = new myKMQuestionnaireRun();
myQTable            c;


    o.parmMyRecId(this.RecId);
    o.set(KMQuestionnaireRunMode::All,this.KMCollectionId, DirPersonUser::find(curUserId()).party());

    o.run();

...

9 Ağustos 2016 Salı

AXAPTA - Invent on hand

//source: http://microsoft-dynamics-ax-erp.blogspot.com.tr/2012/07/find-inventonhand-in-axapta-x.html
static InventOnHand findOnHandByLocationId(ItemId _itemId, InventLocationId _inventLocationId = "")
{
    InventDim           inventDim;
    InventDimParm       inventDimParm;
    InventOnHand        inventOnHand = new InventOnHand();
    ;


    if (_inventLocationId == "")

         return InventOnhand::newItemId(_itemId);

    //Take a combination of dimension , against which you want to find the stock
    inventDim.InventLocationId  = _inventLocationId;

    //Set the flag for the selected dimensions as active
    inventDimParm.initFromInventDim(inventDim);

    //Initialize the inventSumDateDim with Date,item,dimension and dim parameter
    inventOnHand = InventOnHand::newParameters(_itemid,
                                               inventDim,
                                               inventDimParm);

    return inventOnHand;
}