Tuesday, September 24, 2013

Adding lookup method on Form Reference Group AX 2012


Reference Group Control lookups in AX 2012

With the addition of reference groups fields the AX forms including the dialog form gives a rich control called the FormReferenceGroupControl. With this post, I will show you how to add a reference field in the batch dialog form and add a filtered query controlled drop down.

I am going to show with a EcoResCategoryId field. The requirement is to filter out categories with Level 3 and present in the batch dialog dropdown.
 

Class Declaration:
 Declare the warehouse and category fields and dialog fields as below.

InventLocationId            inventLocationId;
EcoResCategoryId            EcoResCategoryId;
DialogField                 DialogInventLocationId,DialogEcoResCategoryId;

Dialog Method:
public Object dialog()
{
    dialog    dialog = new DialogRunbase("@ZON2996",this);


    DialogEcoResCategoryId   = dialog.addField(extendedTypeStr(EcoResCategoryId),"Category");
    DialogInventLocationId   = dialog.addField(extendedTypeStr(InventLocationId),"Warehouse");


    return dialog;
}

DialogPostRun method should be overridden to enable the lookup method of the fields
public void dialogPostRun(DialogRunbase _dialogloc)
{
    super(_dialogloc);
    _dialogloc.dialogForm();
     _dialogloc.dialogForm().formRun().controlMethodOverload(true);
    _dialogloc.dialogForm().formRun().controlMethodOverloadObject(this);
     _dialogloc.formRun().controlMethodOverload(true);
    _dialogloc.formRun().controlMethodOverloadObject(this);

}
Determine the field Id of the control from the dialog form. Personalizing will show you the below form.
From the below form we know that Fld1_1 is the field for the category. Also note that as it is reference group, a Name field is shown that should hold the category information in the string box.


Lookup:
We would need to create a lookup method for the above field as below.
void Fld1_1_lookup()
{
    Query     DropDownquery          = new Query();
    FormControl       frmSTr         = DialogEcoResCategoryId.dialog().formRun().controlCallingMethod();

//Use the SysReferenceTableLookup class instead of SystableLookup class for such reference group control
    SysReferenceTableLookup          sysTableLookup = SysReferenceTableLookup::newParameters(tableNum(EcoResCategory), frmSTr,true);
   
    QueryBuildDataSource     qbds;
    QueryBuildRange          qbr,qbr1;
    ;


    qbds = DropDownquery.addDataSource(tableNum(EcoResCategory));
    qbr  = qbds.addRange(fieldNum(EcoResCategory,Level));
    qbr.value(queryValue(3));
   

    sysTableLookup.addSelectionField(fieldNum(EcoResCategory, Name));
    sysTableLookup.addLookupField(fieldNum(EcoResCategory, ReciD));
    sysTableLookup.addLookupField(fieldNum(EcoResCategory, Name));
    sysTableLookup.addLookupField(fieldNum(EcoResCategory, Code));
    sysTableLookup.parmQuery(DropDownquery);
    sysTableLookup.performFormLookup();

}


Thursday, December 15, 2011

AX 2012: Reference To the VS Projects not updated in AOT



Common error when using a class that runs on server and references a Visual studio DLL file.
I am trying to consume web service from external systems in AX. To do this, I have added the references in VS 2010 solution and that in turn is added to the AOT. I have set the deploy on client and server to yes.





When you add the solution to the AOT, the AX server will store the relevant DLL and its configuration file to the folder under the application as below. The highlighted part is the instance name.
C:\Program Files\Microsoft Dynamics AX\60\Server\Lexjet_DEV_AX\bin\VSAssemblies
When you use the reference to the web services in a class, which is very much simplified in AX 2012 as it gets stored under the VS references, you may want to execute the class always from server. In my case it is a batch job so it becomes mandatory for me.


But when my code tries to create a service client, it points out the configuration path to the client rather than the destination pointed above.


Second Problem with this path reference is that when you try updating a service in VS 2010 and update the project to AOT, only the server folder gets the latest artifacts of the project. Below is a screen that shows that the last modified date of the client folder is older than the one in server.

 
The deploy to client did not work and even though you run the class from server it takes the client’s path reference in the createServiceClient method.
Workaround:
Every time you add or update the service reference, you need to copy the configuration and DLL from server to the client folder.
This is a big overhead when you are developing integration scenarios and you tend to update the service reference again and again.
You also do not want to refer to the client’s directory in case of a batch job. This is a big pain when you are migrate your code to other environments.

Wednesday, September 14, 2011

Importing Vendor Into Ax 2012

Having all the relations of GAB structure changed, it became mandatory to write a script to import vendor data into Ax 2012. I will create a DirParty record and then associate it to vendor fields. The addresses can be attached to the vendor's PartyRecId. The use of views to record all the address fields help to initialize the linked tables.



static void importVendor(Args _args)
{
    CommaIO                     csvFile;
    container                   readCon;
    counter                     icount,inserted;
    Dialog                      dialog;
    DialogField                 dfFileName;
    DirPartyRecId               partyRecId,contactPartyRecid;
    Name                        name,contactName;
    VendTable                   vendtable;
    FileName                    fileName;
    str                         contactperson;
    DirPartyPostalAddressView   addressView;
    DirPartyContactInfoView     contactView;
    ContactPerson               contactpersonTable;
    LogisticsElectronicAddressMethodType enumType;


    DirParty                    dirParty;
    LogisticsPostalAddress      address;
    LogisticsElectronicAddress  logisticsElectronicAddress;
    BinData binData;
    str stringImage;
    inserted =0;
    #File


    dialog = new Dialog("Pick the file");
    dfFileName = dialog.addField(extendedTypeStr(FileNameOpen));
    dialog.filenameLookupFilter(["All files", #AllFiles]);


        if (dialog.run())
        {
             filename =  dfFileName.value();
        }




    csvFile = new CommaIO(filename, 'r');
    
   
    if (csvFile)
    {
        readCon = csvFile.read();
        ttsbegin;
        while (csvFile.status() == IO_Status::OK)
        {
            readCon = csvFile.read();
            icount++;
            if (readCon)
            {
                name = conPeek(readCon,2);
                partyRecId = DirPartyTable::createNew( DirPartyType::Organization, name).RecId;


                vendtable.clear();
                vendtable.initValue();
                vendtable.Party = partyRecId;
                vendtable.AccountNum = conPeek(readCon,1);
                vendtable.VendGroup  = conPeek(readCon,5);
                vendtable.Currency   = conPeek(readCon,6);
                //vendtable.Blocked    =
                vendtable.DlvMode    = conPeek(readCon,8);
                vendtable.PaymMode   = conPeek(readCon,9);
                ContactPerson = conPeek(readCon,12);
                if(contactperson != '')
                {
                    contactname = conPeek(readCon,12);
                    ContactPerson::findOrCreateNameParty(partyRecId,contactname);
                }
        
                vendtable.insert();


                address.CountryRegionId = strLRTrim(conPeek(readCon,14));
                //addressView.State = strLRTrim(conPeek(readCon,16));
                address.ZipCode = strLRTrim(conPeek(readCon,15));
                address.Street  = strLRTrim(conPeek(readCon,19));
               // address.county = strLRTrim(conPeek(readCon,17));
               address.City    = strLRTrim(conPeek(readCon,18));
                addressView.LocationName = name;
                addressView.IsPrimary = NoYes::Yes;
                addressView.Party = partyRecId;
                addressview.initFromPostalAddress(address);


                DirParty = DirParty::constructFromPartyRecId(addressView.Party );
                DirParty.createOrUpdatePostalAddress(addressView);


                contactView.LocationName = "Delivery email";
                contactView.Locator      = strLRTrim(conPeek(readCon,10));
                contactView.Type         = LogisticsElectronicAddressMethodType::Email;
                contactView.Party        = partyRecId;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);


                contactView.LocationName = "Delivery Cellular Phone";
                contactView.Locator      = strLRTrim(conPeek(readCon,11));
                contactView.Type         = LogisticsElectronicAddressMethodType::Phone;
                contactView.Party        = partyRecId;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);


                contactView.LocationName = "Delivery Phone";
                contactView.Locator      = strLRTrim(conPeek(readCon,3));
                contactView.Type         = LogisticsElectronicAddressMethodType::Phone;
                contactView.Party        = partyRecId;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);


                contactView.LocationName = "Delivery Fax";
                contactView.Locator      = strLRTrim(conPeek(readCon,4));
                contactView.Type         = LogisticsElectronicAddressMethodType::Fax;
                contactView.Party        = partyRecId;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);
                inserted++;
            }
        }
        ttsCommit;
    }
    info(strfmt("%1 records inserted out of %2",inserted,icount));
}



Tuesday, October 26, 2010

Ax2009 Reporting services installation Error out on iis

On the Box:
Server: windows 2008 server R2.
SQL 2008.

When installing Reporting Extensions for Ax 2009,the pre-requisite page shows that IIS is not installed even thou you may have installed it. In the log file,you will find that the installation fails at IIS.

For the workaround, install the following IIS components from Manage Your server-> Server Roles->role services.

Install the selected components and You wont be asked to install IIS pre-requisite.


Thursday, October 21, 2010

SQL Database Error in Ax2009

When I try to execute a query which uses complex joins in dynamics ax 2009, the sql buffer size is reached depending upon the buffer size of configuration database size. Here is the error in the infolog.
Error:
The total, internal size of the records in your joined SELECT statement is 25666 bytes, but Microsoft Dynamics is by default performance-tuned not to exceed 24576 bytes.
It is strongly recommended that you split your table(s) into smaller units.
Alternatively, you have to specify a 'Buffer size' value of 26 Kbytes or higher in the 'SQL' tab page in the Microsoft Dynamics Configuration Utility. The default value is 24 Kbytes.


 As a solution, you can increase the buffer size in the ax server configuration manager by multiples of 2. By default it has 24kb of buffer.Also note how the page memory use increases from task manager of 'AX32' services.The increase in buffer id proportional to the increase in PF memory.