Saturday, August 18, 2012

Read XML Product file & store it in to staging table using X++

In this post, I would like to share X++ Code that will help to read XML product file & stored its information in to staging table in AX 2012 using X++

Suppose we have following XML file.


<?xml version="1.0" encoding="utf-8"?>
<!--Products.xml file-->
<Products>
  <Product>
    <OrderItem>010109</OrderItem>
    <UOM>EA</UOM>
    <UnitPrice>0.01</UnitPrice>
    <ManufacturerName>ACCO</ManufacturerName>
    <PictureFileName>S0165591_STD.JPG</PictureFileName>
    <UNSPSC>44122003</UNSPSC>
    <ShortDescribe>BINDER 38610 (YR2B250) YELLOW</ShortDescribe>
    <LongDescribe>Pressboard Binder, 1" Capacity, 11"x8-1/2", Yellow</LongDescribe>
    <Category>Non-Categorized</Category>
    <SubCategory>Non-Categorized</SubCategory>
    <LongWebDescription>Coated pressboard offers excellent moisture resistance with a grained, long-lasting finish. High quality three-ring metal. Opening and closing triggers.</LongWebDescription>
  </Product>
  <Product>
    <OrderItem>ACC38610</OrderItem>
    <UOM>EA</UOM>
    <UnitPrice>0.01</UnitPrice>
    <ManufacturerName>ACCO</ManufacturerName>
    <PictureFileName>S0165591_STD.JPG</PictureFileName>
    <UNSPSC>44122003</UNSPSC>
    <ShortDescribe>BINDER 38610 (YR2B250) YELLOW</ShortDescribe>
    <LongDescribe>Pressboard Binder, 1" Capacity, 11"x8-1/2", Yellow</LongDescribe>
    <Category>Non-Categorized</Category>
    <SubCategory>Non-Categorized</SubCategory>
    <LongWebDescription>Coated pressboard offers excellent moisture resistance with a grained, long-lasting finish. High quality three-ring metal. Opening and closing triggers.</LongWebDescription>
  </Product>
</Products>


And we have following table in AX.


Field Name
Data Type
Comments



VendItem
String50 EDT
Order Item
UOM
String25 EDT
UOM
UnitPrice
String25 EDT
Unit Price
OEMName
String50 EDT
Manufacturer Name
PicURI
String50 EDT
Picture File Name. Note: Assumption that this will point to a URL picture resource from Vendor.
UNSPSC
String50 EDT
UNSPSC
ShortDesc
String50 EDT
Short Describe
LongDesc
String250 EDT
Long Describe
VendCategory
String50 EDT
Category
VendSubCategory
String50 EDT
Sub Category
LongWebDesc
String250 EDT
Long Web Description


now we need to write 2 methods to import XML file data into above table. First method we will write as a table method to check whether imported data is already exists in table or not.


public boolean CheckVendItem(VendItem _vendItem)
{
    scnVendCatInboundCatalog VendCatInboundCatalog;
    ;

    select firstOnly VendCatInboundCatalog where VendCatInboundCatalog.VendItem == _vendItem;

    if ( VendCatInboundCatalog.VendItem == _vendItem)
    return true;
    else
    return false;
}

Second method will responsible to read XML file & insert new record or update existing record in table.


static void XMLReadProduct(Args _args)
{
    #define.paramsNode("Products")
FileIoPermission permission;
XMLDocument doc;
XMLNode rootNode, ProductNode,ProductFieldList;
XMLNodeList ProductList ;
scnVendCatInboundCatalog VendCatInboundCatalog;
XMLParseError xmlError;
int i, countupdate, countinsert;
;
permission= new FileIoPermission("C:\\ABCDEF.xml",'r');
permission.assert();
// Get the XML document
doc = new XMLDocument();
doc.load("C:\\ABCDEF.xml");
xmlError = doc.parseError();
if (xmlError && xmlError.errorCode() != 0)
throw error(strFmt("Error: %1",xmlError.reason()));

rootNode = doc.getNamedElement(#paramsNode);

ProductList = rootNode.childNodes();
for (i = 0; i < ProductList.length(); i++)
{
    ProductFieldList = ProductList.item(i);


    if(VendCatInboundCatalog.CheckVendItem(ProductFieldList.selectSingleNode("OrderItem").text()))
    {
        ttsBegin;
        select forUpdate VendCatInboundCatalog where VendCatInboundCatalog.VendItem == ProductFieldList.selectSingleNode("OrderItem").text();

        VendCatInboundCatalog.VendItem = ProductFieldList.selectSingleNode("OrderItem").text();
        VendCatInboundCatalog.UOM = ProductFieldList.selectSingleNode("UOM").text();
        VendCatInboundCatalog.UnitPrice = ProductFieldList.selectSingleNode("UnitPrice").text();
        VendCatInboundCatalog.OEMName = ProductFieldList.selectSingleNode("ManufacturerName").text();
        VendCatInboundCatalog.PicURI = ProductFieldList.selectSingleNode("PictureFileName").text();
        VendCatInboundCatalog.UNSPSC = ProductFieldList.selectSingleNode("UNSPSC").text();
        VendCatInboundCatalog.ShortDesc = ProductFieldList.selectSingleNode("ShortDescribe").text();
        VendCatInboundCatalog.LongDesc = ProductFieldList.selectSingleNode("LongDescribe").text();
        VendCatInboundCatalog.VendCategory = ProductFieldList.selectSingleNode("Category").text();
        VendCatInboundCatalog.VendSubCategory = ProductFieldList.selectSingleNode("SubCategory").text();
        VendCatInboundCatalog.LongWebDesc = ProductFieldList.selectSingleNode("LongWebDescription").text();

        VendCatInboundCatalog.update();
        ttsCommit;

        countupdate++;
        // info("update successfully");
    }
    else
    {
        VendCatInboundCatalog.VendItem = ProductFieldList.selectSingleNode("OrderItem").text();
        VendCatInboundCatalog.UOM = ProductFieldList.selectSingleNode("UOM").text();
        VendCatInboundCatalog.UnitPrice = ProductFieldList.selectSingleNode("UnitPrice").text();
        VendCatInboundCatalog.OEMName = ProductFieldList.selectSingleNode("ManufacturerName").text();
        VendCatInboundCatalog.PicURI = ProductFieldList.selectSingleNode("PictureFileName").text();
        VendCatInboundCatalog.UNSPSC = ProductFieldList.selectSingleNode("UNSPSC").text();
        VendCatInboundCatalog.ShortDesc = ProductFieldList.selectSingleNode("ShortDescribe").text();
        VendCatInboundCatalog.LongDesc = ProductFieldList.selectSingleNode("LongDescribe").text();
        VendCatInboundCatalog.VendCategory = ProductFieldList.selectSingleNode("Category").text();
        VendCatInboundCatalog.VendSubCategory = ProductFieldList.selectSingleNode("SubCategory").text();
        VendCatInboundCatalog.LongWebDesc = ProductFieldList.selectSingleNode("LongWebDescription").text();

        VendCatInboundCatalog.insert();
        countinsert++;
        // info("insert successfully");
    }

}
    info(strFmt("%1 Update & %2 Insert Done Successfully",countupdate,countinsert));
}

Happy DAX!!!!!



Thursday, August 16, 2012

List of mandatory fields on a table

Hi All,
   The Following Code will let you know the List of Mandatory Fields in a table :-


static void CheckMandatoryFieldsOnTable(Args _args)
{
    DictTable dictTable;
    DictField dictField;
    int i;
    TableId tableId = tablenum(custtable);
    ;
    dictTable = new DictTable(tableId);
    for (i=1 ; i<=dictTable.fieldCnt() ; i++)
    {
        dictField = new DictField(tableId, dictTable.fieldCnt2Id(i));
        if (dictField.mandatory())
        {
            info(dictField.name());
        }
    }
}

Enjoy DAX !!!

How to run AX2012 HyperV Machine on Virtualbox (Step by step guidelines)


    Download virtual box and the extension pack.


2. Once you have installed, create a new virtual machine.


3. Select Windows 2008 64bit


4. Allocate a good portion of memory (4GB recommended)


6. Un-tick the boot Hard Disk. Add disks manual after the wizard is finished.


6. Click on your new virtual image settings


7. Navigate to Storage
Add hard disks by clicking the disk icon – then “Choose existing disk”
Repeat this step for all 3 vhd files.
·         AX2012-DEVEP-SEA-DEV.vhd
·         Base10A-WS08R2-HV.vhd
·         SEA-DEV.vhd


8. After you have finished.


9. Start your image


 
Configure sharepoint 
After you have managed to get it to start, there are a couple other things to be aware of:
1. Start the AOS by going to the windows services and start manually
2. All seems to work except for Enterprise Portal
To fix this modify your hosts file “C:\Windows\System32\drivers\etc\Hosts”
Open this file with notepad and add in the line
                127.0.0.1              Sharepoint
                127.0.0.1              SEA-DEV.contoso.com
It should look like this:


3.
  When you run a report - it will be slow on first run. Don't kill it; leave it for a few minutes. Mine took ~4minutes to run first time. After that, it is very responsive. Standard SSRS caching.




 

Enjoy DAX!!!

Tuesday, August 07, 2012

Silent Client Installation of AX 2009

When you want to set up an AX client without user intervention, do the following.
Export a Config file and place it in a shared location. Eg \\London\client\AX2009.axc
Create a text file in the same directory as the installation file. Insert into it the following:
LogDir="C:\TMP"
HideUi=1
AcceptLicenseTerms=1
InstallClientUI=1
ClientConfig=1
ClientAosServer=LONDON
ClientLanguage=en-us
ClientConfigFile="\\LONDON\client\AX2009.axc"
ConfigurePrerequisites=1
Then just call the setup file from the prompt by using this syntax
d:\setup.exe ParmFile=c:\SilentParamFile.txt

Tuesday, January 31, 2012

Document Handling in AX – setup and Example


Some initial setups for enabling document handling in AX-
On the Tools menu, select Options.
Under Document handling, select Document handling active.
Select Update toolbar line button to highlight the Document handling icon on the toolbar when you select a record with documents references.
Documents are stored in a default document archive directory and before you start creating documents, you must select the location in the Parametersform.
Click Basic > Setup > Document management > Parameters.
In Archive directory, type the path to the archive directory, or use the browse button () to select a folder on your network.
Select the Number sequences tab.
In the Number sequence code list, select the number sequence to use for naming your documents.
The document management system handles several types of documents including letters, worksheets, and simple notes. Before you can create documents of a certain type, the document type must be created in the Document type form. 
By default, all documents are stored in the Archive directory selected on the Parameters form. However you can select alternative folders for the individual document types.
Also by default, all document types are available from all forms, but some document types are only relevant for certain tables, such as, if you only want to create customer letters for records in the Customers form. When you associate a document type with a specific table, it is not possible to create any documents of that type, in other tables.
Create new document type
Click Basic > Setup > Document management > Document types.
Press CTRL+N to create a new document type.
In Type, type a code for the document type.
In Name, type a descriptive name for the document type.
In the Job description list, select the type of document to create.
In the Group list, select a group for the document type.
Now, I would like to explain document handling with an example for sales orders form of DOC type. 
Initially set the parameters for document handling.
Go to – >Basic -> setup -> Document Management – > Parameters form
set the archive diretory path ( where the document has to be stored like c:\AxDocuments). Remember when ever u create document for a record, the document gets stored in the above location specified.
Check – use Active document table checkbox.
In the number sequences tab - select the number sequence you would like to use for the documents.
Then, If you want to enable documents for salestable – Go to – > Basic -> setup -> Document Management – > Active document tables form . Then select the name of the table here as salestable and in enable the always enabled checkBox.
Now when you open the salestable form you can find the document handling enabled on the toolbar for the salestable form. Double click the document handling icon and create a new document for that record by clicking the new button and selecting the Document menuitem button.Now you can create documents for the salestable.Once you create documents the documents will be stored in the archive path selected in the parameters form.
When ever u create a document, it hits docuref and docuvalue tables.
In the docuref,it creates a record with the tableid of the salestable, the record id of the salestable and the dataareaid ..etc..and correspondingly a record gets generated in the docuvalue with all the filenames, extensions,path etc
To view the documents in the salestable from itself, i mean in the gird itself here is the way… 
Open the salestable form, Then , I would like to use icons for every record in the salestable.So i will write a display method at the salestable level.
//BP Deviation Documented
display smmDocIconNum
showDocHandIcon()
{
#macrolib.resource
;
if ((select firstonly docuRef where
docuRef.RefCompanyId == this.DataAreaId && docuRef.RefTableId ==
this.TableId && docuRef.RefRecId == this.RecId).RecId)
{
return #RES_NODE_DOC;
}
return #RES_AM_NEW;
}
Now create a new window control in the gird. Add the datasource as salestable and datamethod as showDocHandIcon.
The main class where all the business logic is written is docuAction Class. Now i am going to use this class to open the documents for the records.
Now please override the Mouseup() method of the window control
public int
mouseUp(int _x, int _y, int _button, boolean _Ctrl, boolean _Shift)
{
int ret;
args args;
docuRef
docuRef;
;
ret =
super(_x, _y, _button, _Ctrl, _Shift);
element.showDocument();  
 // Method at form level
return ret;
}
Now add showDocument() method at form level
void showDocument()
{
args args;
docuref docuref;
;
args = new args();
docuRef =
docuref::find(salesTable.dataAreaId,tablenum(SalesTable),salesTable.RecId,today());
args.record(docuRef);
args.parmEnumType(enumnum(Docucode));
args.parmEnum(Docucode::Open);
docuaction::main(args);
}
NOW YOU CAN VIEW YOUR DOCUMENTS FROM THE GRID ITSELF BY DOUBLE CLICKING THE WINDOW CONTROL. 

ActiveX in Axapta


The Microsoft Axapta Object Server supports Microsoft’s COM (Common Object Model), DCOM (Distributed Common Object Model) and ActiveX controls. This enables Microsoft Axapta to use the advanced flexible COM technology either directly or indirectly using third party applications.

In AX, each ActiveX control will be having a classId. This entry will exaplain you how to use html document ActiveX control in Axapta.

How to add ActiveX control to your form 
  • create form by Name MyActiveXExample
  • MyActiveXExample- > design – > New control -> ActiveX
  • Select html document ActiveX control from the list of activex’s displayed by Ax and name the newActiveX control as HtmlActiveX.
  • Make the Autodeclaration property of the newly created ActiveX control to Yes
  • After that , if you want to display html content in that Activex Control,
  • Add the below code in the init() method of your MyActiveXExample form
public void init()
{
str htmlSource;
COMDispFunction webpreviewWrite;
COMVariant text = new COMVariant();
COM ctrl = new COM();
;
super();
htmlSource = @’ <html><pre><hr color="#99CCFF">
<center>
Search in Google
<FORM method=GET action="
http://www.google.com/search">
<TABLE bgcolor="#FFFFFF"><tr><td>
<A HREF="
http://www.google.com/">
<IMG SRC="
http://www.google.com/logos/Logo_40wht.gif" <br></A>
<INPUT TYPE=text name=q size=31 maxlength=255 value="">
<INPUT TYPE=hidden name=hl value="en">
<INPUT type=submit name=btnG VALUE="Google Search">
</td></tr></TABLE>
</FORM>
</center></pre>
<hr color="#99CCFF"></html>’;
ctrl.attach(HtmlActiveX.interface());
webpreviewWrite = new COMDispFunction(ctrl, ‘write’, COMDispContext::METHOD);
text.bStr(htmlSource);
HtmlActiveX.open("");
webpreviewWrite.call(text);
HtmlActiveX.close();
}
 The above code will allow use to browse through google without opening the web page , becasue i added the html controls and the functionalites to the controls to search in google.

I have mapped the htmlActiveX control to my Com object and i am writing the html string to the comVariant. Open ActiveX control by .open() method.  Finally i am calling my comdispFunction object i.e webpreviewWrite.call(text) to open the content in the Activex. Then i closed my ActiveX control by using .close() method

Wednesday, January 25, 2012

Get AOS server name for current session

The following code obtains the AOS server name for the current session:

static void getServerNameForCurrentSession(Args _args)  
 {  
   sysClientSessions cliSessions;  
   sysServerSessions svrSessions;  
   ;  
   select svrSessions  
     exists join cliSessions  
       where cliSessions.SessionId == sessionID()  
         && cliSessions.ServerID == svrSessions.ServerId;  
   info(substr(svrSessions.AOSId, 1, strfind(svrSessions.AOSId, '@', 1, strlen(svrSessions.AOSId))-1));  
 }  

Create new role center in Dynamics Ax 2009


Compiled from Dynamics Ax Developer help for quick reference.
  1. Open Dynamics Ax enterprise portal (default installation is http://servername/sites/DynamcisAx).
  2. Click on Site Action > Create . Choose Web part page (as most Ax role center using this). Complete the page creation.
  3. Open Ax client > AOT > Web > Web menu item > URLs > New URL.
  4. Specify URL Properties by clicking on the elipsis button. Browse Enterprise portal folder and choose the .aspx page created in the step 2.
    If got error go to here.
  5. Set home page property to YES. (If not the page will not be available to be chosen as user profile role center page).
  6. Right click > Import. This will import the page to AOT under web > web files > page definitions.
  7. Locate the new page definition on step 6. Set the page title properties.
  8. Go to Admin > Setup > User profile. Create a new record. Choose the role center column from drop down.
  9. Click view role center button to test.

Friday, January 20, 2012

Launch AOT forms & Reports without using Classfactory from x++


static void Args_report_Job15(Args _args)
{
    Args    args;
    ReportRun reportRun;
    ;
    args = new Args();
    args.name(reportstr(custtranslist));
    reportRun = new reportRun(args);
    reportRun.init();
    reportRun.run();
}

static void Args_form_Job15(Args _args)
{
    Args    args;
    FormRun formRun;
    ;
    args = new Args();
    args.name(formstr(custtable));
    formRun = new FormRun(args);
    formRun.init();
    formRun.run();
    formRun.detach();
}

Enable UAT database over OneBox DevTest environment using JIT

 Dear Friends, In this Article I will show you how to enable UAT database access for Development machine using just-in-time (JIT). Many time...