25 Haziran 2014 Çarşamba

AX 2012 - Refresh form data

A Subroutine of you called refreshs data. Form's data doesn't refresh. To solve this issue you have to call first research and then refresh. Research doesn't broke your query filters and if you call it with true parameter it goes to current record after refresh:

    LedgerJournalTrans_DS.research(true);
    LedgerJournalTrans_DS.refresh();


If your subroutine is a SysOperation class and your screen doesn't refresh anyway, don't forget add this to your controller class:

 controller.parmExecutionMode(SysOperationExecutionMode::Asynchronous);

If you don't, your research and refresh methods run before your classes completed it's job.

24 Haziran 2014 Salı

AX 2012 - Default dimension

//http://axvuongbao.blogspot.com.tr/2013/08/how-to-create-default-dimension-from-x.html
public static DimensionDefault CreateDefaultDim(Container _a,Container _v)
{

    DimensionAttributeValueSetStorage   valueSetStorage = new DimensionAttributeValueSetStorage();
    DimensionDefault                               result;
    int                                                      i;
    DimensionAttribute                            dimensionAttribute;
    DimensionAttributeValue                   dimensionAttributeValue;
    //_attr is dimension name in table DimensionAttribute
    container               conAttr  =  _a;
    container               conValue =   _v;
    boolean                 _createIfNotFound = true;
    str                     dimValue;

    for (i = 1; i <= conLen(conAttr); i++)
    {
        dimensionAttribute = dimensionAttribute::findByName(conPeek(conAttr,i));

        if (dimensionAttribute.RecId == 0)
        {
            continue;
        }

        dimValue = conPeek(conValue,i);

        if (dimValue != "")
        {
            // _createIfNotFound is "true". A dimensionAttributeValue record will be created if not found.
            dimensionAttributeValue=
                    dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,dimValue,false,_createIfNotFound);

            // Add the dimensionAttibuteValue to the default dimension
            valueSetStorage.addItem(dimensionAttributeValue);
        }
    }
    result = valueSetStorage.save();

    return result;
}


Sample usage:

LedgerJournalTrans.DefaultDimension = MyUtility::CreateDefaultDim("[Contract],[Project]","[0001],[MyBigProject]")

If you get Unable to return DimensionAttributeValue record for ... error than you try create a dimension combination values unavailable in system.

20 Haziran 2014 Cuma

AX 2012 - Query; set Date value with strfmt.

If you want to set date value with strfmr for Axapta queries you have to use Date2StrXpp function:

...   
QBR2.value(strFmt(' ( TransDate >= %1 )' , Date2StrXpp(TransDate) ));
...

17 Haziran 2014 Salı

AX 2012 Add validate method, groupping and labeling parameters with RDP class

Class Declaration:

[
    DataContractAttribute,
    SysOperationGroupAttribute("DateGroup", "Date Range", "1", FormArrangeMethod::Vertical),
    SysOperationGroupAttribute("Other", "Other Filters", "1", FormArrangeMethod::Vertical)
]
class myContract implements SysOperationValidatable

{
...
}

Parm method:

[DataMemberAttribute('StartDate'),
SysOperationGroupMemberAttribute("DateGroup"),
SysOperationDisplayOrderAttribute("1")]
public StartDate parmStartDate(StartDate _StartDate = startDate)
{
   startDate = _StartDate;
   return StartDate;
}


Validate method:

public boolean validate()
{
    boolean isValid = true;
    if ( !endDate || !StartDate)
        isValid = checkfailed("You have to enter first/last dates!..");

    return isValid;
}

AX 2012 Add Query to SSRS report when developing with RDP

Add query attribute to data provider class:

[
    SRSReportQueryAttribute (querystr(Cust)),
    SRSReportParameterAttribute(classstr(myReportContract))
]
class myReportDP extends SRSReportDataProviderBase
{
    ...

}
Get query like this:

[SysEntryPointAttribute(false)]
public void processReport()
{
    QueryRun                    qRun;
    Query                       query;
     ...

    query = this.parmQuery();
    ...



Do not forget make Dynamics Filter property to true at SSRS report Dataset if you want to see select query button.

AX 2012 - Sysoperation class sample

Contract Class:
classDeclaration method:

[DataContractAttribute]
class myTestContract
{
    TransDate       transDate;
    str             packedQuery;
    LedgerJournalId JournalId;
}


Other methods:
//------ for get Query  -------------
public Query getQuery()
{
    return new Query(SysOperationHelper::base64Decode(packedQuery));
}


//---------- parm method sample --------------
[DataMemberAttribute
, SysOperationControlVisibilityAttribute(false)]
public LedgerJournalId parmJournalId(LedgerJournalId _JournalId = JournalId)
{
    JournalId = _JournalId;

    return JournalId;
}

//--------------------- call query with parmQuery  ----------------
[DataMemberAttribute,
    AifQueryTypeAttribute('_packedQuery', querystr(myQuery))
]
public str parmQuery(str _packedQuery = packedQuery)
{
    packedQuery = _packedQuery;
    return packedQuery;
}

//-------------- send query with SetQuery -----------------------
public void setQuery(Query _query)
{
    packedQuery = SysOperationHelper::base64Encode(_query.pack());
}



DataService Class:

ClassDeclaration metodu:
class myDataService
{
}


Batch job method:

[SysEntryPointAttribute]
public void Go(myContract _contract)
{
    QueryRun                            qRun;
    Query                               query;
    QueryBuildDataSource                QBDS;
    QueryBuildRange                     QBR,QBR2;
    CustTable               CustTable;
    LedgerJournalId                     JournalId;
    TransDate                           PaymDate;
    LedgerJournalTrans                  journalTrans;

    JournalId = _contract.parmJournalId();
 

    query = _contract.getQuery();
    QBDS = query.dataSourceTable(tablenum(CustTable));
    QBR = QBDS.findRange(fieldnum(CustTable,CustAccount));
    if (!QBR)
        QBR = QBDS.addRange(fieldnum(CustTable,CustAccount));
    QBR.value(queryValue("000001"));

    qRun = new QueryRun(query);

    while(qRun.next())
    {
        CustTable = qRun.get(tableNum(CustTable));
      ...
    }


Controller Class:
class declaration:
 

class MyController extends SysOperationServiceController
{
}


public static MyController newFromArgs(Args _args)
{
    MyController    controller;
    MyContract      contract;
    LedgerJournalTable             LedgerJournalTable;

    if ( !_args || !_args.caller() )
        throw error("This class needs parameter!..");

    ledgerJournalTable = _args.caller().ledgerJournalTable();
    controller = new ETGVendAdvanceReqController();

    controller.initializeFromArgs(_args);

    contract = Controller.getDataContractObject("_contract");
    contract.parmPaymDate(today());
    contract.parmJournalId(ledgerJournalTable.JournalNum);

    return Controller;
}


public static void main(Args _args)
{
    MyController controller;

    controller = MyController::newFromArgs(_args);

    controller.parmExecutionMode(SysOperationExecutionMode::Asynchronous);
    controller.startOperation();
}

 
Menu item parameters:

Object - MyController
ObjectType - class
Parameters - MyDataService.Go 

AX 2012 - How to read/write Vendor/Customer to LedgerJournalTrans table?

This information store in ledgerDimension field. When writing:

LedgerJournalTrans.LedgerDimension    = DimensionStorage::getDynamicAccount(myVendAccount, LedgerJournalACType::Vend);

When reading you can look up for AccountDisplay or accountNameFind methods or:

DimensionStorage::ledgerDimension2AccountNum(ledgerJournalTrans.OffsetLedgerDimension)
DimensionStorage::ledgerDimension2AccountNum(ledgerJournalTrans.LedgerDimension)

CustTable::findByLedgerDimension(ledgerJournalTrans.LedgerDimension)                                                     VendTable::findByLedgerDimension(ledgerJournalTrans.LedgerDimension)