jeudi 17 février 2011

What are the different types of exceptions

There are many different types of exception and the type differs depending on what caused the error. A majority of exception types are determined by the kernel and are not normally thrown by application code. All exception types, however, can be caught, and it is the developers responsibility to decide which exceptions need to be handled. The exception type is identified using the system enum Exception. Because it is a system enum, it cannot be modified, so users cannot add new exception types. 

Exception Description
info Displays informational exceptions; for example, a certain record has been updated.
warning Indicates the user has performed an illegal, though nonfatal operation.
deadlock Informs the user that the system encountered a deadlock situation in the database.
error Indicates a fatal error has occurred and the transaction has stopped.
internal Displays Microsoft Dynamics AX 2009 internal development errors.
break Indicates that the user has pressed Break or Ctrl+C.
dderror Indicates that an error occurred in the DDE-kernel class.
sequence Undefined.
numeric Indicates that an error has occurred during the use of the str2int, str2int64, or str2num functions.
CLRError Indicates that an error has occurred during the use of the CLR functionality.
CodeAccessSecurity Indicates that an error has occurred during the use of CodeAccessPermission.demand.
UpdateConflict Indicates that an error has occurred in a transaction using Optimistic Concurrency Control, and that the transaction will be retried.
UpdateConflictNotRecovered Indicates that an error has occurred in a transaction using Optimistic Concurrency Control, and that the code will not be retried.

What are the three keywords associated with the Transaction Trancking System and what is their significance

ttsBegin: You mark the beginning of the transaction with ttsbegin

ttsCommit: Your mark the successful end of a transaction with a statement with a ttscommit. This ensures that the transaction has performed as it was supposed to upon completion.

ttsAbort: this can be used as an exception to make a transaction be aborted and rolled back to its state before the ttsbegin. You insert a ttsAbort wherever you want this to occur.

What are the three ways to sort data on a select statement

a- using existing indexes in a table.
b- The order by clause  in  a select statement that will return records in ascending order by default and if specified, can return them in descending order.
c- The group by clause in a select statement will group records by a selected field.

How to build a query in DAX using X++ code

The following code demonstrates how a query is built from scratch in X++. This query returns all sales orders, from the SalesTable, for customer '4008', sorted by the SalesId.

Query query;
QueryRun queryRun;
QueryBuildDataSource qbds;
QueryBuildRange qbr;
SalesTable SalesTable;
;

query = new Query();

//this line attaches a table to the qbds data source object
qbds = query.addDataSource(TableNum (SalesTable));

//this line attaches a range to the 'SalesTable' //data source, the range is the CustAccount
qbr = qbds.addRange(FieldNum (SalesTable,CustAccount));

// The range is set to '2001'
qbr.value ('2001');

// The query will sort by sales id
qbds.addSortField (FieldNum(SalesTable,SalesId));

// The queryRun object is instantiated using the query
queryRun = new QueryRun(query);

// The queryRun object loops through all records returned
while (queryRun.next())
{

// The current record is assigned to the salesTable variable
SalesTable = queryRun.get(tableNum(SalesTable));

print SalesTable.SalesId;

How to use Joins in DAX

Use joins to link tables so that they can return values together. By default, inner joins are created. The following table describes the types of joins available:

Join Type Use to...
inner Combine records into one table only when there are matching values in a common field.
outer Combine records into one table even if there are no matching values in the common field.
exists Combine records from one table whenever a value exists in a common field in another table.
notexists Combine records from one table whenever a value in a common field in another table does not exist.

Not only is there additional syntax needed to specify what table is being joined, but the where clause also has to be modified. Within the where clause, the two fields that relate the tables must be specified in addition to any other conditions of the search. When using an inner or outer join the table buffers of both tables are populated with the retrieved records. An exists or not exists join only populates the first table.

How to select statement keywords

The following table contains keywords used in select statements and their descriptions:

 
Syntax Category
Keyword
Description
Find Options
reverse
Returns records in reverse order.

firstFast
Speeds up the fetch. This is a priority hint that means the first row appears quicker but the total return time may be slower. A typical use of this option is dialog updates.

firstOnly
Speeds up the fetch. This tells Microsoft Dynamics AX to fetch only the first record.

forUpdate
Selects records exclusively for update. The operation performed on the fetched records is update. Depending on the database, records may be locked for other users.

noFetch
Indicates that no records are fetched. This is used when the result of the select is passed to another application object; for example, a query that performs the fetch.
Aggregate
sum
Returns the sum of the fields from the rows given by the group by clause. Can be used to sum all accounts, order lines, and so on.

avg
Returns the average of the fields from the rows given by the group by clause.

minof
Returns the minimum of the fields from the rows given by the group by clause.

maxof
Returns the maximum of the fields from the rows given by the group by clause.

count
Returns the number of fields from the rows given by the group by clause.
Sorting Options
order by
Instructs the database to sort selected records by fields in the order by list.

group by
Instructs the database to group selected records by fields in the order by list.
Direction
asc
Sorts the order by or group by clause in ascending order.

desc
Sorts the order by or group by clause in descending order.
Index Clause
index
Sorts the selected records as defined by the index.

index hint
Gives the database a hint to use this index to sort the selected records as defined by the index. The database may ignore the hint.
Join Clause
exists
Returns a record only if the linked record exists.

notexists
Returns a record only if the linked record does not exists.

outer
Returns all records regardless of whether linked records exist.

lundi 14 février 2011

How to use Sets data structure in Axapta

The Set class is used for the storage and retrieval of data from a collection in which the values of the elements contained are unique and serve as the key values according to which the data is automatically ordered.

Solution with Sets
 
Declare set in Form\class declaration

Set                         setChangedRecord;

Initialize set on Form\DataSource\init as follows:

setChangedRecord     = new Set(Types::Record);

Store records in set on Write method of the data source as follows
 if (!setChangedRecord.in(purchReqLine))
    {
        setChangedRecord.add(purchReqLine);
    }
Traversing of records in Set:

Following is the way of traversing records from Set

SetEnumerator   setEnumerator    = setChangedRecord.getEnumerator();
 while (setEnumerator.moveNext())
            {
                reqLine = setEnumerator.current();
                if (!reqLine.IsSaved)
                {
                    purchReqLineLocal = PurchReqLine::findRecId(reqLine.RecId,true);
                    purchReqLineLocal.IsSaved = true;
                    purchReqLineLocal.update();
                }
            }

What is the difference between List , Set, Container and Map

Follow this link


Enjoy It !

mercredi 9 février 2011

How to use Inheritence proprety in DAX

Following project illustrates how we can use Inheritence  of classes in DAX


Happy Daxing!

Why we use Dynamic language

Dynamic languages are one of the most interesting fields in programming, because it gives the developer more functionality & flexibility in developing applications.

The reasons of this are
The ability to modify the code in runtime, which saves the time of compiling, linking and building the application.You can imagine editing the code that runs on a robot walking on Mars from earth, this actually happened in NASA using LISP, and imagine how difficult this can be if you were using compiled languages.

Usually the dynamic language codes are less complicated than static language codes.
Usually dynamic languages support both Object Oriented and Functional Oriented models of programming.

Portability level is always higher in interpreted languages

Dynamic language syntax is usually easier and shorter if compared with equivalent codes in other compiled language

When and How to use Cacheaddmethod

Caching of display methods has been introduced to improve the performance of display and edit functions if they are calculated on the AOS, and to improve the performance when records are transferred from the server to the client.

Cacheaddmethod adds a display method to the cache. Once calculated the result of the method is passed to the client. Only display methods may be cached and only methods on table may be cached.
<formdatasource>.cacheAddMethod(str _methodName [,boolean _updateOnWrite = true])
_methodName
the name of the display method of the table used in this datasource
_updateOnWrite
if true, the content of the cache will be refreshed on record write.
The cache is refreshed on reread and create.
The display method is added to the cache in the init() method of the form datasource. 

void init()
{
    super();
 
    this.cacheAddMethod(tableMethodStr(ProjJournalTrans, ProjName));
}

Happy Daxing!

How to connect MSSQL DataBase with X++ Code.

As part of Customer requirements , sometimes we need to connect to DataBase otherthan Axapta DataBase. So let us explore how it can be done with X++ code.
In Ax using ODBCConnection and LoginProp its possible to connect to Database on remote server, as illustrated in the following example.I tried the following code on MSSQL Server.

static void test_ODBCConnection(Args _args)
{
    LoginProperty loginProp;
    ODBCConnection conn;
    Resultset resultSet, resultSetCount; // get record
    Statement statement1, statement2; // Create SQL Statement
    ResultSetMetaData metaData ; // get Record metadate like columnname.
    ;

    // Set Server Database
    loginProp = new LoginProperty();
    loginProp.setServer('SON15092');
    loginProp.setDatabase('AdventureWorksDW');

    // Create Connection and SQL Statement
    conn = new ODBCConnection(loginProp);
    statement1 = conn.createStatement();
    resultSet = statement1.executeQuery("SELECT * from DimTime");

    while (resultSet.next())
    {
        metaData = resultSet.getMetaData();
        info("Column Name :"+metaData.getColumnName(1)+" Value ="+resultSet.getString(1));
    }
}
Happy Daxing!

How to count Records in Query using X++

Following code illustrates how we can use SysQuery::countTotal() method to get the number of records in Query.

static void Query_cntRecords(Args _args)
{
    Query                query = new Query();
    QueryRun             queryRun;
    QueryBuildDataSource qbd;
    ;
   
    qbd = query.addDataSource(tablenum(CustTable));
    queryRun = new QueryRun(query);
   
    info(strfmt("Total Records in Query %1",SysQuery::countTotal(queryRun)));
   
}

Happy Daxing!

How to add an image as a resource in DAX

You can use an image as a resource in Dynamics AX: 



And use it in a method display returning a bitmap:

public display Bitmap ShowMyResource( )
{
    ;
    return SysResource::getResourceNodeData(SysResource::getResourceNode('LogoCertification_bmp'));
}


Happy Daxing!

X++ Code Optimzation

Following are the coding tips to improve your Axapta system's performance:

1. Smart Joins : Try to Use Joins instead of nested while loop wherever possible.

2. Select Statement : Mention the field names in the select statement instead of feteching entire row , this will reduce data amount to transfer from database.
e.g " Select Itemid from inventTable "

3. Display Methods : Make sure that generic display methods should be moved at table level and cached by using"Formdatasource.cacheAddmethod".

4. Local caching : Use Variables for storing the constantly used caculated values in loop , by doing so you can reduce the calls to the database and different layers.

5. Monitor the Database Calls : For bulk records updation,deletion,insertion use RecordSet Based operator like update_recordset , delete_from and insert_recordset .

6. Aggregate Function: Use sum, avg, minof, maxof and count where applicable. Because this can utilize the database’s built-in function instead of calculating and analyse data in Axapta. 

Keep following things in your mind before you start coding in Ax.
1. Whenever you came accross new functionality , don't start coding immediately please first cross check whether the same/similar kind of functionality is there in the standard product. By doing so you will save time for coding,learn ax coding style and also this will help you to understand the various functionalities in the standard product.
2. Start with pseudo-code , just draw sketch on paper how you want the data to flow , which will help you in understanding the different override methods in Axapta.
3. Code should be modular , Instead of writing all the code in one method please write plug and play functions. 

mardi 8 février 2011

How to hide content Pane in DAX for developers

Here is the code : ) 

static void hideContentPaneWindow(Args _args)
{

       #WinApi
       HWND contentPane =   WinApi::findWindowEx( WinAPI::findWindowEx(infolog.hWnd(), 0,    'MDIClient', ''),0,'ContentFrame','' );
       ;
       if (contentPane)
       WinApi::ShowWindow(contentPane,#SW_HIDE); //To restore use          #SW_RESTORE
}

Happy Daxing!

How to identify multiple selected records in Grid using X++

Steps :

1. Create a new method on form and copy the following code.
2. Next create a button on form . and call the method on the button click event.
(for the button property makesure the Multiselect should be set to yes , or else by default for multiple selection system will disable the buttons)

public void checkSelectedRecords()
{
    VendTable inventLocal;
    ;
    //getFirst method gets all the selected records in the grid
    inventLocal = VendTable_ds.getFirst(true);

    while (inventLocal)
    {
        info(strfmt("You selected Item %1",inventLocal.AccountNum));
        // get the next selected record
        inventLocal = VendTable_ds.getNext();
    }
}

Happy Daxing!

How to build your own context menu on Form field

Context menu on field are nothing but the list of features shown when you do right click on field like filter by field,by selection ,setup etc.
Following code illustrates how you can override the standard context menu and build your own .
Best use of this is in-case of display methods where filter by field and selection are not available.
Override the standard context method available on Form fields.


public void context()
{

   PopupMenu menu ;
   Str filterValue;
   int selectedItem;
   int filter, removeFilter;
   ;

//super(); // Comment standard menu

   menu = new PopupMenu(element.hWnd());
   filter = menu.insertItem("Filter");
   removeFilter= menu.insertItem("Remove Filter");

   selectedItem = menu.draw();
   filterValue = element.design().controlName("Table1_Usn").valueStr();

   switch (selectedItem)
   {
      case filter :
         Table1_ds.filter(fieldnum(table1,Usn),filterValue);
      break;

      case removeFilter :
         Table1_ds.removeFilter();
      break;

   }
}

Happy Daxing!

How to use Str Variable in SQL Where Expression, in DAX

When trying to use unbounded string variable within a select / where expression , it is expecting a limited sized string , so the solution is to limit the size of variable as below

static void StrCompiler(Args _args)
{
    str 20                  ItemId;
    InventTable             inventTable;
    ;
   
    select inventTable
    where inventTable.ItemId == ItemId;

}

Eventhough we are using string EDT's we won't get this error , because each string EDT will have its size. 

Happy Daxing!

How to read data from Word file using X++

Try this following job :)

static void FileIO_ReadFromWord(Args _args)
{    
    str         document = "C:\\Demo Edition.docx";
    COM         wordApplication;
    COM         wordDocuments;
    COM         wordDoc;
    COM         range;
    TextBuffer  txt = new TextBuffer();
    ;

    // Create instance of Word application
    wordApplication = new COM("Word.Application");

    // Get documents property
    wordDocuments = wordApplication.Documents();

    // Add document that you want to read
    wordDoc = wordDocuments.add(document);
    range = wordDoc.range();

    txt.setText(range.text());

    // to replace carriage return with newline char
    txt.replace('\r', '\n');
  
    info(txt.getText());
}

Happy Daxing!

How to export an image to an Excel file

Use the following job :)

static void ExportImageToExcel(Args _args)
{
    COM comApplication;
    COM comWorkbooks;
    COM comWorkbook;
    COM comWorksheet;
    COM comShapes;

    COMVariant variant = new COMVariant();
    COMVariant xpos = new COMVariant();
    COMVariant ypos = new COMVariant();
    COMVariant state = new COMVariant();
    COMVariant width = new COMVariant();
    COMVariant height = new COMVariant();

    SysExcelWorksheet excelWorksheet;
    SysExcelCells excelCells;
    ;

    //Create the Excel app and grab the workbooks
    comApplication = new COM('Excel.application');
    comWorkBooks = comApplication.workbooks();

    //Wrap the rest in an exception to make sure excel is closed
    try
    {
        //Create a new workbook and get a reference to it
        variant.int(-4167);
        comWorkBook = comWorkBooks.add(variant);
        comWorkSheet = comApplication.activeSheet();
        //Add some text to the worksheet
        excelWorksheet = SysExcelWorkSheet::construct(MSOfficeVersion::Office2007, comWorksheet);
        excelCells = excelWorksheet.cells();
        excelCells.item(10,1).value("Hello world");

        //Set up image parameters
        variant.bStr("c:\\temp\\hello.bmp");
        xpos.int(1);
        ypos.int(1);
        state.int(1);
        width.int(100);
        height.int(100);
        //Add the image to the worksheet
        comShapes = comWorkSheet.shapes();
        comShapes.addPicture(variant,xpos,ypos,state,state,width,height);

        //Autofitt and protect the sheet
        excelworksheet.columns().autoFit();
        excelWorksheet.protect('',true,true);

        //Save the sheet and close the app
        comWorkBook.saveas("c:\\temp\\hello.xls");
        comWorkBooks.close();
        comApplication.quit();
    }
    catch(Exception::Error)
    {
        //Force app to quit
        comWorkBook.saveas("c:\\temp\\hello.xls");
        comWorkBooks.close();
        comApplication.quit();
    }

}

Happy Daxing!

How to read Data from an Excel file

Try the following job :)

static void ReadExcel(Args _args)
{

SysExcelApplication application;
SysExcelWorkbooks workbooks;
SysExcelWorkbook workbook;
SysExcelWorksheets worksheets;
SysExcelWorksheet worksheet;
SysExcelCells cells;
COMVariantType type;
int row;
ItemId itemid;
Name name;
FileName filename;


;

application = SysExcelApplication::construct();
workbooks = application.workbooks();
//specify the file path that you want to read
filename = "C:\\item.xls";
try
{
    workbooks.open(filename);
}
catch (Exception::Error)
{
    throw error("File cannot be opened.");
}

workbook = workbooks.item(1);
worksheets = workbook.worksheets();
worksheet = worksheets.itemFromNum(1);
cells = worksheet.cells();
do
{
   row++;
   itemId = cells.item(row, 1).value().bStr();
   name = cells.item(row, 2).value().bStr();
   info(strfmt('%1 - %2', itemId, name));
   type = cells.item(row+1, 1).value().variantType();
}
while (type != COMVariantType::VT_EMPTY);
   application.quit();
}

Happy Daxing!

How to export Data from Dynamics AX to an Excel file

How it works
1. Use SysExcelApplication class to create excel file.
2. Use SysExcelWorkbooks and SysExcelWorkbook to create a blank workbook(by
default 3 worksheets will be available).
3. Use SysExcelWorkSheets to select worksheet for writing data.
4. SysExcelCells to select the cells in the excel for writing the data.
5. SysExcelCell to write the data in the selected cells.
6. Once you done with write operation use SysExcelApplication.visible to open
file. 

Try the following code :)

static void ExportDataToExcelFile(Args args)
{

    CustTable custTable;
    SysExcelApplication application;
    SysExcelWorkBooks    workbooks;
    SysExcelWorkBook     workbook;
    SysExcelWorksheets  worksheets;
    sysExcelWorksheet   worksheet;
    SysExcelCells       cells;
    SysExcelCell        cell;
    int                 row;

    ;

    application = SysExcelApplication::construct();
    workbooks = application.workbooks(); //gets the workbook object
    workbook = workbooks.add();  // creates a new workbook
    worksheets = workbook.worksheets(); //gets the worksheets object

    worksheet = worksheets.itemFromNum(1);//Selects the first worksheet in the workbook to insert data
    cells = worksheet.cells();
    cells.range('A:A').numberFormat('@');  // numberFormat ‘@’ is to insert data as Text

    while select custTable
    //The following loop will provide the data to be populated in each column
    {
        row++;
        cell = cells.item(row,1);
        cell.value(custTable.AccountNum);
        cell = cells.item(row,2);
        cell.value(custTable.Name);
        cell = cells.item(row,3);
        cell.value(CustTable.CustGroup);
        cell = cells.item(row,4);
        cell.value(CustTable.Currency);
        cell = cells.item(row,5);
        cell.value(CustTable.CreditMax);
        cell = cells.item(row,6);
        cell.value(CustTable.CreditRating);
    }
    application.visible(true); 
    // opens the excel worksheet
}

Happy Daxing!

How to create an Excel File using X++

Use the following job :)

static void createExcel(Args _args)
{
    SysExcelApplication         excel;
    SysExcelWorkBooks           books;
    SysExcelWorkBook            book;
    Filename                    excelFileName;

    boolean createShowDialog()
    {
        Dialog      dialog = new Dialog('Create excel');
        DialogGroup                 dlgGrpExcelPath;
        DialogField                 dialogExcelPath;
        container   filterCriteria;
        ;

        dlgGrpExcelPath      = dialog.addGroup('Excel file name',dlgGrpExcelPath);
        dialogExcelPath     = dialog.addField(typeid(FileNameSave),'File name');

        filterCriteria  = ['*.xls','*.xls'];
        filterCriteria  = dialog.filenameLookupFilter(filterCriteria);

        if (dialog.run())
        {
            excelFileName = dialogExcelPath.value();
            return true;
        }
        return false;
    }
    ;

    if (!createShowDialog())
    {
        return;
    }

    excel        = SysExcelApplication::construct();

    excel.displayAlerts(false);
    books = excel.workbooks();
    if (excel.workbooks().count())
    {
        excel.workbooks().close();
    }
    book = books.add();
    book.saveAs(excelFileName);
    excel.quit();
}

Happy Daxing !

lundi 7 février 2011

How to create a text File in Dynamics Ax

Use BinData class to create a simple text file using axapta.
Firstly create an instance of a TextBuffer class and append text using textBuffer.AppendText. Pass it to binData what you want to write using binData.setStrData and then write using binData.saveFile.
See this following code:

static void WriteFile(Args _args)
{
    CustTable   custTable;
    BinData     binData;
    TextBuffer  textBuffer;
    ;

    textBuffer = new TextBuffer();
    textBuffer.setText('');

    while select custTable where custTable.AccountNum < '40020'
    {
        textBuffer.appendText(strfmt('%1 \n',custTable.AccountNum));
    }

    textBuffer.getText();

    binData = new BinData();
    binData.setStrData(textBuffer.getText());
    binData.saveFile(@"c:\iba.txt");

}

Happy Daxing!

How to build a section in a report using X++

In the Init method of your report Write this code:

public void init()
{
    ReportSection           reportSection;
    DictTable               dictTable;
    Counter                 fieldCounter;

    super();

    reportSection = element.design().autoDesignSpecs().addSection(ReportBlockType::Body);
    reportSection.table(tableNum(custTable));

    dictTable = new DictTable(tableNum(custTable));

    while (fieldCounter < 10)
    {
        fieldCounter++;
        reportSection.addControl(dictTable.id(), dictTable.fieldCnt2Id(fieldCounter));
    }
}
This code displays the required fields from the query without having a design in your report.

Happy Daxing!