Wednesday, 28 December 2016

ledger Dimension creation

        journalTrans.parmAccountType(str2enum(accType,c4));
        switch(journalTrans.parmAccountType())
        {
            case LedgerJournalACType::Ledger:
                accEntryPattern = [strFmt("%1-%2-%3-%4-%5",c5,c6,c7,c8,c9),c5];
                if(c6)
                {
                    accEntryPattern += "Division";
                    accEntryPattern += c6;
                    dimcount++;
                }
                if(c7)
                {
                    accEntryPattern += "Region";
                    accEntryPattern += c7;
                    dimcount++;
                }
                if(c8)
                {
                    accEntryPattern += "Branch";
                    accEntryPattern += c8;
                    dimcount++;
                }
                if(c9)
                {
                    accEntryPattern += "Department";
                    accEntryPattern += c9;
                    dimcount++;
                }
                if(c43)
                {
                    accEntryPattern += "Employee";
                    accEntryPattern += c43;
                    dimcount++;
                }
                if(c44)
                {
                    accEntryPattern += "Customer";
                    accEntryPattern += c44;
                    dimcount++;
                }
              accEntryPattern = conIns(accEntryPattern,3,dimcount);
              journalTrans.parmLedgerDimension(AxdDimensionUtil::getLedgerAccountId(accEntryPattern));






public void createJournalLines_Second()
{
    #define.INR("INR")
    GOD_IntegrationPostingProfile       integrationPostingProfile;
    container                           dimensionValues;
    int                                 i;
    DimensionDisplayValue               membership;
    NumberSeq                           numberSeq;
    NumberSeq                           numSeqVoucher;
    GOD_CashAccountMapping              CashAccountMapping;
     DimensionDynamicAccount             ledgerdimension;
    DimensionDefault                dimensionDefaultnew;


    //
    DimensionDefault dimensionDefault;
    LedgerDimensionAccount ledgerDimensionAccount;
    int        dimcount =0;
    container       accEntryPattern;
    //
    ;

    hasError =false;
    integrationPostingProfile                   = this.getIntegrationPostingProfile();
    LedgerjournalTrans.clear();

    numberSeq                                   = NumberSeq::newGetVoucherFromId((ledgerjournalname.NumberSequenceTable));
    ledgerJournalTrans.Voucher                  = numberSeq.voucher();

    LedgerjournalTrans.Company                  = curext();
    ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, Company));

    ledgerJournalTrans.JournalNum               = LedgerjournalTable.JournalNum;
    LedgerJournaltrans.initFromLedgerJournalTable_LT(ledgerJournalTable);

    if(tpmsPJStagingDB.CurrencyCode && Currency::exist(tpmsPJStagingDB.CurrencyCode))
    {
        ledgerJournalTrans.CurrencyCode         = tpmsPJStagingDB.CurrencyCode;
        ledgerJournalTrans.ExchRate             = Currency::exchRate(LedgerjournalTrans.CurrencyCode);
    }
    else
    {
        errorLog += "@IMT238";
        hasError = true;
    }

    ledgerJournalTrans.PaymReference            = tpmsPJStagingDB.Paymentreference;
    ledgerJournalTrans.Prepayment               = tpmsPJStagingDB.Prepayment;
    ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, Prepayment));

    //Modified by 21929 on 27/5/2016 to fetch item groups from integration parameters for
    //prepayment journals
    if(tpmsPJStagingDB.Prepayment == NoYes::No)
    {
        ledgerJournalTrans.TaxGroup                 = integrationPostingProfile.SalesTaxGroup;
        ledgerJournalTrans.TaxItemGroup             = integrationPostingProfile.SalesTaxMainGroup;
    }
    else
    {
        ledgerJournalTrans.TaxGroup                 = integrationParameter.SalesTaxMainGroup;
        ledgerJournalTrans.TaxItemGroup             = integrationParameter.SalesTaxGroup;
    }

    ledgerJournalTrans.AmountCurCredit         = tpmsPJStagingDB.AmountCurCredit;
    ledgerJournalTrans.TransDate                = tpmsPJStagingDB.TransDate;
    ledgerJournalTrans.DocumentNum              = tpmsPJStagingDB.DocumentNum;
    ledgerJournalTrans.DocumentDate             = tpmsPJStagingDB.TransDate;
    ledgerJournalTrans.AccountType              = LedgerJournalACType::Ledger;
    ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans,AccountType));

    if(tpmsPJStagingDB.CashPayment == NoYes::Yes)
    {
         CashAccountMapping = GOD_CashAccountMapping::find(tpmsPJStagingDB.Vertical,tpmsPJStagingDB.Location);

    }
       // ledgerJournalTrans.LedgerDimension =      this.getLedgerDimensionWithFD(CashAccountMapping.MainAccountIddebitset2);
       // if(tpmsPJStagingDB.CustAccount)
    /*{
        if(CustTable::exist(tpmsPJStagingDB.CustAccount))
        {
            ledgerJournalTrans.LedgerDimension          = DimensionStorage::getDynamicAccount(tpmsPJStagingDB.CustAccount, LedgerJournalACType::cust);
            ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, LedgerDimension));
        }
        else
        {
            hasError = true;
            errorLog += strFmt("@IMT270", tpmsPJStagingDB.CustAccount);
        }
    }
    ledgerJournalTrans.LedgerDimension          = DimensionStorage::getDynamicAccount(tpmsPJStagingDB.CustAccount, LedgerJournalACType::cust);
    ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, LedgerDimension));
    else
    {
        hasError = true;
        errorLog += "@IMT136";
    }*/

                accEntryPattern = [strFmt("%1-%2",CashAccountMapping.MainAccountIddebitset2,tpmsPJStagingDB.Vertical),CashAccountMapping.MainAccountIddebitset2];
                if(tpmsPJStagingDB.Vertical)
                {
                    accEntryPattern += "Verticals";
                    accEntryPattern += tpmsPJStagingDB.Vertical;
                    dimcount++;
                }


                accEntryPattern = conIns(accEntryPattern,3,dimcount);
              ledgerDimension = AxdDimensionUtil::getLedgerAccountId(accEntryPattern);


     //ledgerDimension = AxdDimensionUtil::getMultiTypeAccountId(enumNum(LedgerJournalACType),LedgerJournalACType::Ledger,[CashAccountMapping.MainAccountIddebitset2,CashAccountMapping.MainAccountIddebitset2]);
    dimensionDefaultnew = this.findDefaultDimension( tpmsPJStagingDB.Vertical,tpmsPJStagingDB.Location,tpmsPJStagingDB.Event);

    ledgerJournalTrans.LedgerDimension          = DimensionDefaultingService::serviceCreateLedgerDimension(ledgerDimension,str2int64(tpmsPJStagingDB.Vertical));//,DimensionDefault);
    //DimensionStorage::getDefaultAccountForMainAccountNum(CashAccountMapping.MainAccountIddebitset2);//, LedgerJournalACType::Ledger);
    ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, LedgerDimension));
    //dimensionValues                             = GOD_getFinancialDimensionsByRecId(CustTable::find(tpmsPJStagingDB.CustAccount).DefaultDimension);



      //dimensionValues                               = GOD_getFinancialDimensionsByRecId(MainAccount::findByMainAccountId(CashAccountMapping.MainAccountIddebitset2).RecId);
     //dimensionValues = GOD_getFinancialDimensionsByRecId(5637164306);

        for(i=1; i<=conLen(dimensionValues); i+=2)
    {
        if(conPeek(dimensionValues,i) == #Membership)
        {
            membership  = conPeek(dimensionValues,i+1);
            break;
        }
    }

     //LedgerjournalTrans.defaultdimension = ledgerJournalTable.DefaultDimension;
   LedgerjournalTrans.defaultdimension         = this.DimensionDefault(membership);
   LedgerjournalTrans.OffsetDefaultDimension   = this.DimensionDefault(membership);
    ledgerJournalTable.DefaultDimension         = this.DimensionDefault(membership);
    ledgerJournalTrans.PostingProfile           = custLedgerAccount.PostingProfile;
    ledgerJournalTrans.OffsetAccountType        = this.getOffsetAccountType();
    ledgerJournalTrans.OffsetLedgerDimension    = this.CreateLedgerDimensionsforcashsecond(ledgerjournalname.OffsetLedgerDimension,LedgerjournalTrans.defaultdimension);

    if(!ledgerJournalTrans.OffsetLedgerDimension)
    {
        errorLog += "@IMT272";
    }

    if(CustPaymModeTable::find(tpmsPJStagingDB.PaymMode) || !tpmsPJStagingDB.PaymMode)
    {
        LedgerjournalTrans.PaymMode             = tpmsPJStagingDB.PaymMode;
    }
    else
    {
        LedgerjournalTrans.PaymMode = "";
        errorLog += "@IMT253";
    }

    Numseqvoucher = null;


}

Thursday, 3 November 2016

Deleting duplicate Record from Table – Ax2012

Deleting duplicate Record from Table – Ax2012


Sometimes we lost unique identity check in the tables while doing some customization in Dynamics AX. It may happen due to failure of database synchronization.
Here is the code to remove the duplicate records from a table.
static void RemoveDuplicates(Args _args)
{
Set fieldSet = new set(Types::Integer);
DictIndex dictIndex = new DictIndex(
tablenum(PurchTable),
indexnum(PurchTable,PurchIdx));
int i;
;
if(dictIndex.numberOfFields())
{
for(i=1;i<=dictIndex.numberOfFields();i++)
{
fieldSet.add(dictIndex.field(i));
}
ReleaseUpdateDB::indexAllowDup(dictIndex);
ReleaseUpdateDB::deleteDuplicatesUsingIds(tablenum(PurchTable),0, fieldSet);
ReleaseUpdateDB::indexAllowNoDup(dictIndex);
}
info("Successfully done");
}

Sunday, 23 October 2016

Blank Page Issues – SSRS Reports


 I talked about discussing extra space issues aka ‘Blank page issues’ Dynamics AX. So, today we will walk through the problem and try to find a solution (or a set of possible solutions) that works every time. With that said, I would like to point out that the ‘Blank page issue’ is such a black-hole in itself that no one can ever guarantee that following some specified set of steps would save you from falling into that ditch, but this will serve as an pro-active attempt to reduce the percentage of getting into trouble.

So, what is this blank page issue actually?

At first glance, when you print your recently modified report to the screen it looks like it is working the way it is supposed to. But, actually if you try to print the same report or save it to pdf you will realize that it is printing an extra page. This extra page can be at the end of the report (in this case, only one extra page is printed in total) or there could be one normal, one blank page, one normal and one blank page which has now doubled the amount of pages you actually needed.

So, why does this Blank page issue arise?

There could be many answers to this, some experts would argue it’s the settings some would say it’s the developer and we would certainly discuss all those arguments when going through the solution. But for now, I will keep it simple; this happens (in most cases) when you have content flowing beyond the body size of the report.

Blank Page Solutions

1)      Make sure that the page you are actually using in the printer is specified correctly in the Report print setting, for example if you are using European A4 instead of US Letter(mostly used) you would need to specify that change(by default it is set to US Letter). Reason being, European A4 (8.3 x 11.7 inches) and US Letter (8.5 x 11 inches) have different dimensions.
2)      Make sure that the Body size is set to correct limits. Body Width = Page Width – Left Margin – Right Margin, so for US Letter the Body size would be <=7.5in (8.5 – (0.5+ 0.5)) and similarly for European it should be 7.3in.
When we take a look at the VS report for FreeTextInvoice we find that the Body size is 8.11in which is more than 7.5in and hence causing the blank page issue.
If you absolutely cannot make your report work in the Body Size of <=7.5, the only other option you have left is to actually modify (decrease) the margin(Left, Right) size; the basic rule while playing with this page width and body size properties are that your actual Report width should not go beyond the defined Page width.
3)      If you believe that for any reason you may have accidentally changed the column (or textboxes) width while re-arranging some of the textboxes or if you have added new columns (or textboxes) it is the high time that you take a note of those new additions or changes because it is highly prominent that this is causing the blank page issue.
My dear friend Bill suggested that we can color those textboxes that we recently monkey’ed with, reason being that this will allow you to actually visualize which textboxes are actually going over-width when we see the corresponding color printed on the 2nd page (blank). This is very easy and also saves developer a lot of hit and trial time.
4)      There is a property called ‘CanGrow’ for textboxes, MSDN specifies that if set to True, it will allow the section or control to grow vertically so that all data it contains can be printed or previewed. We need to make sure that we have this property set to False.
5)      In the Report properties, Set ConsumeContainerWhiteSpace property to True.
6)      Under Print destination settings – Properties – Check “override default settings”:
7)      Try minimizing the white space at the end of the Report, this is purely a work-around.

For other blank page problems in Microsoft Dynamics AX, check out the related posts.

Friday, 14 October 2016

Get selected records in a grid on a form AX - X++

Get selected records in a grid on a form AX - X++

To get selected record(s) in a grid in AX, we use the MultiSelectionHelper class. To achieve that, follow the steps below:

1.  Create a command button on the form and override the clicked method.
2.  Insert the code below:


void clicked()
{
    MultiSelectionHelper          selectionHelper = MultiSelectionHelper::construct();//Create instance of class
    Set                           selectedRecords = new Set(Types::Record);//Declare a set of type record
    MyLinesTable                  tableLines; //Your table buffer
    super();

    selectionHelper.parmDataSource(MyLinesTable_DS); //Set the datasource
    tableLines  = selectionHelper.getFirst(); //assign to table buffer the reference to selected record(s)

    if (tableLines.RecId)
    {
        while (tableLines)
        {
            selectedRecords.add(tableLines);
            info(strFmt('Selected record.. %1',tableLines.myField));//Display selected record
            tableLines = selectionHelper.getNext();
        }
    }
}

3. Select record(s) on the grid then click on the command button to view the selected records.

Highlighting all the records in a grid (including NOT loaded ones)
Let’s say we have some Control in a Form of type CheckBox, Button or StringEdit and we want it them once modified/clicked to update the form grid by selecting all the records in a grid.
To speed up form load, Dynamics AX will only display/load, say, first 20 records out of, say, 500 available, and those remaining 480 will be loaded when you scroll down the form window.
Most of the time by saying “select all”, we mean all 500 records rather then those 20 visible/loaded ones. So in order to do that, please use this function, which is applied to modified() method of Form Control.
// CheckBox Control
public boolean modified()
{
    // Not a main data source of the Form!
    InventDim    inventDimTMP;

    boolean ret;

    ret = super();

    if(CheckBoxSelectAll.value())
    {
        inventDimTMP = InventDim_DS.getFirst();

        while(inventDimTMP)
        {
            InventDim_DS.findRecord(inventDimTMP);
            InventDim_DS.mark(true);
            inventDimTMP = InventDim_DS.getNext();
        }
    }

    return ret;
}
Now, if you want to do the same, but by replicating CTRL+SHIFT+END keyboard combination and also give your users this informative warning, use this function:
// CheckBox Control
public boolean modified()
{
    boolean ret;

    ret = super();

    if(CheckBoxSelectAll.value())
    {
        // Marks first record. CTRL+SHIFT+END taskid == 2842
        element.task(2842);
        // Marks all records
        element.task(2842);
    }

    return ret;
}
Do you want to continue selecting lines and to load all lines now?

Highlighting all the records in a grid (ONLY loaded ones)

And if you only want to select records that are visible/loaded, you can use CRTL+A equivalent.
// CheckBox Control
public boolean modified()
{
    boolean ret;

    ret = super();
    #task

    if(CheckBoxSelectAll.value())
    {
        // // Marks all records. CTRL+A taskid == #taskSelectAll
        element.task(#taskSelectAll);
    }

    return ret;
}

Highlighting/selecting a specific record in a grid (including NOT loaded records)

Let’s say your records has some unique meaningful identifiers such as serial numbers and you want to select a record in a grid by typing it’s serial number in StringEdit field.
// StringEdit Control
public boolean modified()
{   
    // Not a main data source of the Form!
    InventDim    inventDimTMP;
    boolean serialFound = false;

    boolean ret;

    ret = super();

    inventDimTMP = InventDim_DS.getFirst();

    while(inventDimTMP && !serialFound)
    {
        InventDim_DS.findRecord(inventDimTMP);
        if(inventDimTMP.inventSerialId == this.valueStr()) 
        {
            InventDim_DS.mark(true); 
            serialFound = true;
        }
        inventDimTMP = InventDim_DS.getNext();
    }

    return ret;
}

  

Friday, 7 October 2016

Passing form caller and menu item caller in ax 2012

Passing form caller and menu item caller in ax 2012

form : SalesCreateOrder
form : method 
private void god_sample()
{
    //
    Object      myCaller;
    FormRun     callerForm;
//
     //
       if (element.args())
    {
        myCaller = element.args().caller();

        if (myCaller && myCaller is SysSetupFormRun)
        {
            callerForm = myCaller;
            if (callerForm.name() == formStr(GOD_SalesTableListPage) &&
                (callerForm.args() &&
                    (callerForm.args().menuItemName() == menuitemDisplayStr(GOD_SalesTableListPage))))

            {
                salesTable.GITL_SampleSO = NoYes::Yes;
                salesTable.doUpdate();
               // update_recordset salesTable
           // setting GITL_SampleSO = NoYes::Yes;

            }  
 
        }
    }
    //
 
}



salestable : form 
datasource  : salestable > create

void  create(boolean  append = true)
{
    Object      myCaller;
    FormRun     callerForm;

    SalesTable    newSalesTable;
    TMSSalesTable newTMSSalesTable;
    MCRSalesTable newMCRSalesTable;
    MCRSalesTableShipping newMCRSalesTableShipping;
    MCRSourceCode       mcrSourceCode;
    CustTable           custTableLocal;

    salesTableForm.interCompanyAutoCreateOrders();

    element.editSales(true);

    mcrParmsSet = false;
    // If we are called from CustomerService and we already have
    // created a Sales Order do NOT allow ctrl-n.
    if (salesTable.SalesId && mcrCustomerServiceParm)
    {
        return;
    }

    // Refactored logic to run do not allow open order logic in a separate method.
    // Need to know whether or not the new create was allowed, if it is not
    // return out of the create function.
    if (!element.mcrCheckOpenOrder())
    {
        return;
    }

    // Initialize the image for each line to a "blank" image.
    if (enableDirectedSelling)
    {
        mcrImageUrl = '';
    }

    // If we were called from CustomerService or CustTable and we need to
    // create a new Sales Order do it here and not in SalesCreateOrder.
    // Added new parameter of FormOpenModeForNew
    if (mcrCustomerServiceParm    != MCRCustomerServiceParam::None
        && mcrCustomerServiceParm != MCRCustomerServiceParam::Add
        && mcrCustomerServiceParm != MCRCustomerServiceParam::FormOpenModeForNew)
    {
        if(element.args().record().TableId == tableNum(CustTable))
        {
            custTableLocal = element.args().record();
        }
        salesCreateOrderForm = SalesCreateOrderForm::construct(salesTableForm.defaultSalesType(),
                                                               salesTableForm.project());
        // When coming from cust service or cust maintenance, open form in simple mode.
        if (!salesTable.SalesId)
        {
            super(append);

            if (!salesTableType)
            {
                salesTableType = salesTable.type();
            }

            //Only setfocus if on the correct form view
            if(tabPageDetails.isDisplayed())
            {
                lineViewTab.setFocus();
            }
            salesTableType.formMethodDataSourceCreate(element, salesTable_ds);

            salesTable.CustAccount = custTableLocal.AccountNum;


            salesTable.transferCustAccount();

            ttsbegin;

            salesTableType.formMethodDataSourceWrite(element, salesTable_ds);
            if (salesTable.ProjId)
            {
                salesTable.initFromProjInvoiceTable();
            }


            salesTable.insert();

            // Records that the order has been opened and which one it is.
            if (enableOrderCompletion)
            {
                openOrderSalesTable = salesTable.data();
            }

            ttscommit;

            if (isSalesTableExtensionTHEnabled || isSalesTableWEnabled)
            {
                salesTable_DS.research(true);
            }

            // If creating a sales order from a new customer from CustTable
            if(mcrCustomerServiceParm == MCRCustomerServiceParam::CreateNew)
            {
                mcrSalesTable.SourceId = custTableLocal.mcrCustTable().OrigSourceId;

                mcrLastSourceId = mcrSalesTable.SourceId;

                ttsbegin;
                SalesTable::find(salesTable.SalesId, true);
                mcrSourceCode = MCRSourceCode::construct(salesTable);
                mcrSourceCode.mcrInitFromSourceCodeSetup(MCRSourceCodeSetup::find(mcrSalesTable.SourceId), salesTable.CustAccount);
                salesTable.update();
                ttscommit;

                salesTable_ds.refresh();
                // Immediatlly refresh the sales line
                salesLine_ds.executeQuery();
                salesLine_ds.refresh();
            }
            // Set field as touched so that when a user clicks off that record,
            // validateWrite is called.
            this.forceWrite(true);
        }
    }
    else
    {
        if(salesTableForm.create())
        {
            if (skipLinkActive)
            {
                skipLinkActive = false;
                if (!linkActiveHeaderExecuted)
                {
                    this.linkActive();
                }
            }

            newSalesTable = salesTableForm.salesTable();

            if (newSalesTable)
            {
                super(append);

                //added by 21927 GITL_FRS_OPR_014 start
                if (!GITL_CustomizationExemptionProfile::find(#OPR_014))
                {
                    ttsBegin;
                    newSalesTable.selectForUpdate(true);
                    newSalesTable.GITL_DocumnetDate =   DateTimeUtil::date(newSalesTable.createdDateTime);
                 
                    //07102016
                     //
    if (element.args())
    {
        myCaller = element.args().caller();

        if (myCaller && myCaller is SysSetupFormRun)
        {
            callerForm = myCaller;
            if (callerForm.name() == formStr(GOD_SalesTableListPage) &&

                    (callerForm.args().menuItemName() == menuitemDisplayStr(GOD_SalesTableListPage)))

            {
                newSalesTable.GITL_SampleSO = NoYes::Yes;
                    

            }
        }
    }
    //
                    //07102016
                 
                    newSalesTable.update();
                    ttsCommit;
                }
                //added by 21927 GITL_FRS_OPR_014 end
                salesTable.data(newSalesTable);

                salesTable_ds.cacheCalculateMethod(tableMethodStr(SalesTable, editContactPersonName));

                salesTable_DS.rereadReferenceDataSources();

                // <GEERU>
                if (isRU)
                {
                    salesTable_RU.data(SysExtensionSerializerExtensionMap::findByBase(salesTable_RU.TableId,
                                                                                      salesTable.RecId,
                                                                                      true));
                    salesTable_RU_DS.rereadReferenceDataSources();
                }
                // </GEERU>
                // <GBR>
                if (BrazilParameters::isEnabled())
                {
                    salesTable_BR.data(SysExtensionSerializerExtensionMap::findByBase(salesTable_BR.TableId,
                                                                                      salesTable.RecId,
                                                                                      true));

                    salesTable_BR_DS.rereadReferenceDataSources();
                }
                // </GBR>
                // <GIN>
                if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoIN]))
                {
                    salesTable_IN.data(SysExtensionSerializerExtensionMap::findByBase(salesTable_IN.TableId,
                                                                                        salesTable.RecId,
                                                                                        true));

                    salesTable_IN_DS.rereadReferenceDataSources();
                }
                // </GIN>

                // <GEERU><GBR>
                if (isRU || BrazilParameters::isEnabled())
                {
                    salesTable_ds.refresh();
                }
                // </GBR></GEERU>

                //<GTH>
                if (isSalesTableExtensionTHEnabled)
                {
                    salesTable_DS.research(true);
                }
                //</GTH>

                if (isSalesTableWEnabled)
                {
                    salesTable_W.data(SysExtensionSerializerExtensionMap::findByBase(salesTable_W.TableId,
                                                                                    salesTable.RecId,
                                                                                    true));

                    salesTable_W_DS.rereadReferenceDataSources();
                    salesTable_DS.refresh();
                }

                lineViewTab.setFocus();

                // Context is now editing. If FormOpenMode is ForNew, change it to ForEdit
                if (TradeFormHelper::isOpenedForNew(element.args()))
                {
                    element.args().parmEnum(enum2int(FormOpenMode::ForEdit));
                }
            }
        }
        else
        {
            // If form was opened for the intent of creating new record, and with the given caller, then close form
            if (TradeFormHelper::isOpenedForNewFromForm(element.args()))
            {
                element.close();
            }
            else
            {
                element.editSales(salesTableForm.editHeaderAllowed(), salesTableForm.deleteHeaderAllowed());
            }
        }
    }

    if (!tmsSalesTable.isTmp()) // No need to query for TMSSalesTable if it is disabled
    {
        newTMSSalesTable = TMSSalesTable::find(salesTable.SalesId);

        tmsSalesTable.data(newTMSSalesTable);
        tmsSalesTable.reread();
    }

    element.refreshRetailDatasource();

    if (mcrCallCenterEnabled)
    {
        newMCRSalesTable = MCRSalesTable::findSalesId(salesTable.SalesId);
        if (newMCRSalesTable)
        {
            mcrSalesTable.data(newMCRSalesTable);
        }

        newMCRSalesTableShipping = MCRSalesTableShipping::findSalesId(salesTable.SalesId);
        if (newMCRSalesTableShipping)
        {
            mcrSalesTableShipping.data(newMCRSalesTableShipping);
        }

        // If the create is being done from customer maintenance via customer service and
        // allowOpenOrders is off, then set the boolean to true so that we will not run
        // salesTable/LinkActive/Super which tries to save the salesTable record and prompts
        // that there can not be open orders.
        if (mcrCustomerServiceParm == MCRCustomerServiceParam::CreateNew
            && enableOrderCompletion)
        {
            enterOrderFromNewCust = true;
        }

        // For when new sales orders are created to set focus to the line.
        if(! (MCROrderParameters::find().mcrSourceCodeRequired && mcrSalesTable.SourceId == '')
            && salesLine_ItemId.isDisplayed()) //Only setfocus if on the correct form view
        {
            salesLine_ItemId.setFocus();
        }
    }

    skipLinkActive = false;
}

Filter on AX2012 Listpage

Filter on AX2012 Listpage





Hi Folks J

Today’s post will help you when you need to have customize filter on list page form in AX 2012:

As shown below:

















Shown above is “smmActivitiesListPage” where we have 3 different filter fields:
  •  Activity number [String]
  •   Responsible [Reference group]
  •  Status [Customized Enum field, which consist of 3 element: All, Open, Closed]

Let’s observe how each of this helps in filtering smmActivities record on the list page.

 Activity number field [string]
This is the normal string field added in the group filter of ListPage, and assigned the corresponding EDT [smmActivityId] to get appropriate lookup. As shown in field properties “FilterExpression” is the one which we input in the filter box, “FilterDatasource” provides the datasource under form which need to be filtered and “FilterField” is the one which need to be filtered in the datasource field.




Responsible worker: As we do not have direct string field to select the employee name, so using the smmActivityWorker EDT under reference group to display all the employee name under lookup. 























ActivityStatus [Customized new enum field]:

Since this is new fields which is a type of enum and consist of 3 elements: All, Open, Closed
  • All – It has to display all the records in smmActivitiesListPage form.
  • Open – Filter the records where activity status are open i.e. 0 value.
  • Closed - Filter the records where activity status are closed i.e. 1 value.

As shown below in the FilterExpression new method [getActivityStatus (%1 = status)] name was written along with the parameter which accepts the ActivityStatus.



New method need to be created in the SysQueryRangeUtil class with the required parameter [status in my case] as shown below:

Note: if you are passing the string value in the parameter %1 can be written as “%1”. 






Thanks, & Keep Daxing J Enjoy the new R3 release

Wednesday, 28 September 2016

passing parameters between forms in AX

passing parameters between forms in AX

In dynamics AX, working with forms, there are times when you need to pass some information from current form to the opened form, so the question arrived is that what’s the best way to open the new form and pass information.

Answer: It depends upon the information that is needed in the new form; there is Args class that plays an important role to pass the information. Let’s take a look on some of the important methods of that class
Args class (Argument)
“The Args class is used to pass arguments such as a name, a caller, and parameters between application objects”
Some important methods are
Caller
Gets or sets the instance of the object that created this instance of the Args class.
name
Gets and sets the name of the application object to call.
parm
Gets or sets a string that specifies miscellaneous information for the called object.
parmEnumGets or sets the enumeration value of the enumeration type that is specified in the parmEnumType method.
parmEnmType
Gets or sets the ID value of any enumeration type.
ParmObject
Gets or sets an instance of any object to pass to the called object.
record
Gets and sets the record from the table on which the caller object is working.
There are four methods that can be used to pass extra information to the new class:
  1. The parm method – to pass strings
  2. The parmEnum and parmEnumType method – to pass enumeration values
  3. The parmObject method – to pass an object of any type.
Examples:
1.      If you need a data from the parent form main data source for the current record, so you don’t need to do anything in parent, just create a display menu item and give the form name that needs to be opened, create a menuItem button and assign the newly created menu item.
Override the Init method on opened form
And you get the parent dataset records as
element.args().record()
2.      Need to pass any object/string/Enum
Use the same approach for creating the button
Parent form
void clicked()
{
Args args;
FormRun formRun;super();args = new Args(formstr(FormName));
 // To pass any string value
args.parm(<stringlue>);
 // To pass any object
args.parmObject(<object>);
 // To pass any Enum
       args.parmEnum( EnumValue);
args.parmEnumType( EnumNum( <EnumName>) );
 formRun = classFactory.FormRunClass(args);
formRun.init();
formRun.run();
formRun.wait();
formRun.detach();
parenttable_ds.refresh(); // Refreshing parent table DataSourceTable
parenttable_ds.executeQuery(); // Refreshing Parent DataSourceTable
}
Child Form
void init()
{
args = element.args();
    // get string parameter
<string> = args.parm();
    // get object parameter
    <object> = args.parmObject();
    // get enum parameter
if( element.args().parmEnumType() == EnumNum( <EnumName>) )
{
<enum contol/variable>  =( element.args().parmEnum() );
}
}3.      There are many parameters that you need to pass to the child form.
               In that scenario, you need to create an extra class (parameter/contract class), you can first set the parameters in the init method for that class, use the parmObject for setting and gets the object on the child form
=======================================================================================

Argument Passing between Forms in Dynamics Ax 2009

Here a sample code to pass argument to one form to another form and using of Args() class.
Steps:
1) Create two Forms named FormA and FormB
2)Use the EmplTable as the Datasource of both forms
3)Design FormA with one Grid and add 4 data fields to the Grid(EmplId,DEL_Name,Grade,EmplStatus…..)
4)Assign the datasource for the grid and the data fields
5)Add a Button in FormA
6)Override the Clicked() method and write the below code:
void Clicked()
{
Args    _args;
FormRun _formRun;
EmplId   _empId;
;
_empId = EmplTable.EmplId;  // Selected employee id in the Grid is assigned to the variable which is pass to the next form
_args = new Args(); // creating a object for args class
_args.name(formstr(VA_FormB));  // Form Menuitem
_args.caller(this);  // Form Caller(Current Form is mentioned as this)
_args.parm(_empId); // Employee Number is passed to next form[but parm() is not a best practise]
_args.record(EmplTable); // Table name is passed
_formRun = ClassFactory.formRunClass(_args); //new FormRun(_args);   // Creating object for FormRun
_formRun.init();   // Form Initialization for Load
_formRun.run();  // Form Run for process
_formRun.wait(); // Form Wait for Display
}
7) Open the Second Form – FormB
8) Add one Grid Control and set the Data Source is EmplTable
9) Add 4 data fields as same in the Form A
10)Now Override the Init() of Form
public void init()
{
parmid      _parmId;
EmplTable   _EmplTable;
//     DictTable   _dictTable;    FormBuildDataSource   _ds;    FormBuildGridControl frmGrid; // These are for dynamicForm creation so leave it
_parmId =  element.args().parm(); // Getting the argument value from the Caller
//info(int2str(element.args().record().TableId));
if(!element.args().caller())   // Check the form is called by caller or directly, if directly it throw error
throw error(“Cant Run Directly”);
if(element.args().record().TableId == tablenum(EmplTable))   // check if the sent Table and the Current form table are equal or not
{
//        _EmplTable = element.args().record();  // Assign the Received Table name to Local Variable
//_dictTable = new DictTable(element.args().record().TableId);  // leave it , is used for Dynamic Form Creation
//_ds = form.addDataSource(_dictTable.name());  // leave it , is used for Dynamic Form Creation
//_ds.table(_dictTable.id());   // leave it , is used for Dynamic Form Creation
//frmGrid = form.addControl(FormControlType::Grid, “Grid”);   // leave it , is used for Dynamic Form Creation
//frmGrid.dataSource(_ds.name());   // leave it , is used for Dynamic Form Creation
//info(strfmt(“%1     %2″,_EmplTable.EmplId,_EmplTable.DEL_Name));
//frmGrid.addDataField(_ds.id(),fieldnum(EmplTable, DEL_Name));  // leave it , is used for Dynamic Form Creation
//        EmplTable_EmplId.dataSource(_EmplTable);   // leave it , is used for Dynamic Form Creation
//        EmplTable_EmplId.dataField(fieldnum(EmplTable,EmplID));   // leave it , is used for Dynamic Form Creation
//        EmplTable_DEL_Name.dataSource(_EmplTable);   // leave it , is used for Dynamic Form Creation
//        EmplTable_DEL_Name.dataField(fieldnum(EmplTable,EmplId));  // leave it , is used for Dynamic Form Creation
//        EmplTable_DEL_Email.dataSource(_EmplTable);   // leave it , is used for Dynamic Form Creation
//        EmplTable_DEL_Email.dataField(fieldnum(EmplTable,EmplId));   // leave it , is used for Dynamic Form Creation
super();  // Form Initialization
}
else
{
info(“DataSet Not Received”);  // throw error
}
}
11)Override the Init() of the DataSource
public void init()
{
switch(element.args().dataset())// get the table id sent by caller
{
case tablenum(EmplTable):  // check the table if matches with this tableid
{
_EmplID  =   element.args().parm();  // get the argument value
query   = new Query();            queryBuildRangeProj =                                          query.addDataSource(tablenum(EmplTable)).addRange(fieldnum(EmplTable,EmplId));          // query build for the form to display
queryBuildRangeProj.value(_emplId); // Criteria for the form
EmplTable_ds.query(query); // execution of the query
break;
}
}
super(); //datasource  initialization on the form based on the criteria
}
12) Save it, and create two menu items for each.
13) It is important to change the runon property of the FormB as CalledFrom.
14)Run the FormA and select an Employee Record and click the button.
15)The FormB opens with the Related information of the Selected Employee on form.
===========================================================================

Passing values between forms

For passing parameters from one form to another a special class Args is usually used.
Example:
The code of button click event of FormA which calls FormB and passes some parameters to that form.
void clicked()
{
    // Args class is usually used in Axapta for passing parameters between forms
    Args            args;
    FormRun         formRun;
    // Our custom made class for passing complex set of parameters
    FormBParams     formBParams = new FormBParams();
    Array           items = new Array( Types::String );
    int         i;
    ;

    args = new args();

    // Our values which we want to pass to FormB
    // If we want pass just simple string we can use 'parm' method of 'Args' class
    args.parm( strValue.text() );
    // We also can pass enum value to FormB
    args.parmEnum( NoYesEnumValue.selection() );
    args.parmEnumType( EnumNum( NoYes ) );
    // and also can pass a cursor pointing to some record (in our case it is EmplTable )
    args.record( EmplTable );

    // If we want pass more complex set of parameters we can develop our own class
    // just for passing our parameters.
    formBParams.parmSomeDate( someDate.dateValue() );
    formBParams.parmSomeTime( someTime.value() );
    for( i=0; i<ListBox.items(); i++ )
    {
        items.value( i+1,  ListBox.getText( i ) );
    }
    formBParams.parmItems( items );
    // Pass our object to FormB
    args.parmObject( formBParams );

    // Run FormB
    args.name( formstr( FormB ) );
    formRun = classFactory.formRunClass( Args );
    formRun.init();
    formrun.run();
    formrun.wait();

    if( formrun.closedOk() )
    {
        answerFromFormB.text( args.parm() );
    }
    super();
}
The code of init method of FormB
public void init()
{
    EmplTable       emplTableRecord;
    FormBParams     formBParams;
    Array           items;
    int             i;
    ;
    super();

    // Check for passed arguments
    if( element.args() )
    {
        // get string parameter
        strValue.text( element.args().parm() );

        // get enum parameter
        if( element.args().parmEnumType() == EnumNum( NoYes ) )
        {
            NoYesEnumValue.selection( element.args().parmEnum() );
        }
        // get object parameter
        if( element.args().parmObject() )
        {
            formBParams = element.args().parmObject();
            items       = formBParams.parmItems();
            for( i=1; i<=items.lastIndex(); i++ )
            {
                ListBox.add( items.value(i) );
            }
            someDate.dateValue( formBParams.parmSomeDate() );
            someTime.value( formBParams.parmSomeTime() );
        }
        // get record parameter
        if( element.args().record() && element.args().record().TableId == TableNum( EmplTable ) )
        {
            emplTableRecord =  element.args().record();
            emplName.text( emplTableRecord.Name );
        }
    }
}
The code of ok button click event of FromB
void clicked()
{
    super();
    element.args().parm( strAnswer.text() );
    element.closeOk();
}
The above code is cut out from a demo which you can download here.
===========================================================================
For passing parameters from one form to another a special class Args is usually used.
Example:
The code of button click event of FormA which calls FormB and passes some parameters to that form.
void clicked()
{
    // Args class is usually used in Axapta for passing parameters between forms
    Args            args;
    FormRun         formRun;
    // Our custom made class for passing complex set of parameters
    FormBParams     formBParams = new FormBParams();
    Array           items = new Array( Types::String );
    int         i;
    ;

    args = new args();

    // Our values which we want to pass to FormB
    // If we want pass just simple string we can use 'parm' method of 'Args' class
    args.parm( strValue.text() );
    // We also can pass enum value to FormB
    args.parmEnum( NoYesEnumValue.selection() );
    args.parmEnumType( EnumNum( NoYes ) );
    // and also can pass a cursor pointing to some record (in our case it is EmplTable )
    args.record( EmplTable );

    // If we want pass more complex set of parameters we can develop our own class
    // just for passing our parameters.
    formBParams.parmSomeDate( someDate.dateValue() );
    formBParams.parmSomeTime( someTime.value() );
    for( i=0; i<ListBox.items(); i++ )
    {
        items.value( i+1,  ListBox.getText( i ) );
    }
    formBParams.parmItems( items );
    // Pass our object to FormB
    args.parmObject( formBParams );

    // Run FormB
    args.name( formstr( FormB ) );
    formRun = classFactory.formRunClass( Args );
    formRun.init();
    formrun.run();
    formrun.wait();

    if( formrun.closedOk() )
    {
        answerFromFormB.text( args.parm() );
    }
    super();
}
The code of init method of FormB
public void init()
{
    EmplTable       emplTableRecord;
    FormBParams     formBParams;
    Array           items;
    int             i;
    ;
    super();

    // Check for passed arguments
    if( element.args() )
    {
        // get string parameter
        strValue.text( element.args().parm() );

        // get enum parameter
        if( element.args().parmEnumType() == EnumNum( NoYes ) )
        {
            NoYesEnumValue.selection( element.args().parmEnum() );
        }
        // get object parameter
        if( element.args().parmObject() )
        {
            formBParams = element.args().parmObject();
            items       = formBParams.parmItems();
            for( i=1; i<=items.lastIndex(); i++ )
            {
                ListBox.add( items.value(i) );
            }
            someDate.dateValue( formBParams.parmSomeDate() );
            someTime.value( formBParams.parmSomeTime() );
        }
        // get record parameter
        if( element.args().record() && element.args().record().TableId == TableNum( EmplTable ) )
        {
            emplTableRecord =  element.args().record();
            emplName.text( emplTableRecord.Name );
        }
    }
}
The code of ok button click event of FromB
void clicked()
{
    super();
    element.args().parm( strAnswer.text() );
    element.closeOk();
}

Labels

#veryusefulcode (1) AIF (8) AOT Maps (1) Args (1) Ax 2009 Reports (2) AX 2012 navigation (1) Ax 2012 Interview Questions (1) AX 7 (2) AX Architecture (1) Ax Backup (1) AX Workflow (2) AX2012 (1) AX2012 R2 (1) Ax2012R3 (1) AX2012R3 Dynamics Connector Step by Step Installation and Configuration (1) AX2012R3 EP Step by Step Installation and Configuration EP R3 (1) AX2012R3 HelpServer Step by Step Installation and Configuration (1) AX2012R3 Rapid Start Connector Step by Step Installation and Configuration (1) AX2012R3 Report Server and Analysis Server Step by Step Installation and Configuration (1) AX7 (1) Best practices (1) Blocking user to enter (1) Collection Classes (1) Container (1) D365FO (3) Data Migration Frame Work ax 2012R3 (1) Deleting duplicate Record from Table – Ax2012 (1) Delivery due date notification workflow in Ax 2012 (1) Development Steps EP (1) Dimensions (1) DIXF (1) DMF in Ax 2012 R3 (1) Dynamics Ax 2012 Interview Questions (1) DYNAMICS AX 2012 INTERVIEW QUESTIONS PART 2 (1) DYNAMICS AX 7 (1) EDT relation Migration Tool (1) EP AX 2012 (1) Ep Lookup (1) Error (1) Event Handler (1) F5 (1) File Handling (4) Filter on AX2012 Listpage (1) filtering (2) financial dimensions in AX 2012 (3) form (1) images (1) Installation and Configration (4) Installation and Configuration (11) Installation of Management Reporter 2012 for AX 2012 (1) Interaction class in ax 2012 (1) Interview Question (1) Interview Questions For Ax 2012 (1) Invent DIm (1) Jobs (2) license (1) List page and form menuitem enable code (1) Methods (1) microsoft Dynamics AX 365FO (1) Number Sequence Generation – AX 2012 (5) Number Sequence2012 (1) OLTP-OLAP (1) Passing Args (1) Passing form caller and menu item caller in ax 2012 (1) Passing Multiple Records Args (1) Posting in Ax 2012 (1) POSTING PURCHASE ORDER (1) Query (1) Query Filter Form (2) Query Ranges in X++ (1) Question and Answer (1) Report (1) Reports Controller class (1) RLS in ax 2009 (1) SALES ORDER IMPORT/EXPORT FRAMEWORK BY DMF (1) Security (1) security roles (1) Security Sysqueryrangeutil (1) Sharepoint 2016 (1) SQL SERVER (1) SSRS (2) SSRS Reports Controller class (2) Table collections & Virtual company (1) Time (1) TIPS AND TRICKS (1) Web service AIF (3) Web Services on IIS (AIF) Step by Step Installation and Configuration (1) workflow ax2012 (1) Workflow installation (1) Workflow Method (3) X++ (1)