Wednesday, July 27, 2011

strRem Function - Delete a Character from String - AX 2009

The following code searches a specified string character and deletes it. The cool thing about this function is that it is case sensitive.

str strRem(str text1, str text2)
text1  The string from which to remove characters.
text2 The characters to exclude from the output string.

For example:

strRem("MynameIs","is"); //Returns the string "MynameI".

Wednesday, July 20, 2011

Create Electronic Invoice to Text File Format - Ax 2009 -

 The following code is to create a company country specific requirement. In addition, the logic is specific to the needs of my customer, but I'm sure you will be able to find great examples on how to create directories with WinApi and manipulate text files with the TextIO function.

The project flow is as follow:

1- The user posts an invoice
2- After the invoice has been posted, the KMN_eInvoiceCreation class is called with parameters  (This call is not posted here)
3- The class has several methods from creating the path file name, to writing a very specific logic into a text file.
4- The class saves the file into a specific location

The project produces the following text file contents:

DC|3.0|||15/07/2011|Pago en una sola exhibición||150.22|||||270.02||I
EM|KIE9512187VA|Compania de Ventanas S.A.

DF|Juytyu|130|Piso 7 y 8, Desp.801|Lostre|||MiguelHidalgo|DF|Mexico|999
RC|TORE621221HP9|Elizabeth Araya Reyes

CN|1.00|||Libro de Respuestas 3A/2A/A|25.00|25.00
CN|1.00|||Diploma de Finalización 7A|2.61|2.61
CN|1.00|||Diploma de Finalización 6A|2.61|2.61
CN|1.00|||Flashcards 1-50|120.00|120.00

This project uses a custom table to store all the SalesParmTable data as we needed to provide a way for the user to re-run a posted invoice.

The following are the base enums I'm using.

Friday, July 15, 2011

Monday, July 11, 2011

Create loop from an AX form DataSet - Ax 2009

Sometimes we need to loop through values at the form level. The following code loops (for loop) the SalesParmTable in the CloseOk() Form method.        

        //Create Lines
        for (localSalesParmTable = salesParmTable_ds.getFirst();
              localSalesParmTable = salesParmTable_ds.getNext())


Code to check for "garbage" in the ReleaseUpdateScripts table - AX 2009

ReleaseUpdateScripts    releaseUpdateScripts;
Counter                 total;
Counter                 invalid;
while select ClassID
    from    releaseUpdateScripts
    group by ClassID
    if (classid2name(releaseUpdateScripts.ClassID) == '')
info(strfmt(@"Found %1 invalid classIds out of %2", invalid, total));

Wednesday, July 6, 2011

Workaround to Exception::CLRError using System.IO.StreamWriter

In one of my projects I was using the System.IO.StreamWriter to write data into a text file in X++. Everything went well until I started testing for exception in order to handle them (the System.IO is a .Net class that allows us to maniluplate file operations, including folders. So, I though in catching the exception with the Exception::CLRError one. )

The problem I was having was that when an exception was raised by a problem creating the file (Incorrect file name), the operation will not fall into the Exception::CRLError exception, Instead, it would just crash and I wasn't able to properly handle the exception.

The reason for this is that when using an AX class that runs on the server, the exception never comes back to the client and therefore cannot be handled correctly. I'm using the SalesFormLetter class main method to call my own class after an invoice is generated, and this class (SalesFormLetter) is (1) an abstract class and (2) runs on the server and I really did not want to do this.

A workaorund is to use the TextIO class in AX along with the FileIoPermission. For example, when using the TextIo to create (and/or overwrite) a file, we get a null value when the file could not be created (and/or overwritten). Then, we can throw an exception when the object is null.

In my case I have a central class that handles all errors, so when the TextIO object is null, I call this class and I throw an error, then the error comes back to my method and falls into the Exception::Error exception.

The following is the code