Dynamics AX 2012 Complete Architure

Hi,

At a high level, the following snap will give you an overview of the Dynamics AX 2012 architecture and its supported technologies....


Welcome the next big version of Dynamics AX :)

Dynamics Ax 2012 Installation Pre-requisites

Hi ,

Following snap will give you an insight into the Dynamics Ax 2012 components and their supported operating systems.




  
  Enjoy the new ax installation :)

Get Online Currency Exchange Rate in Dynamics Ax 2009

Hi,

If you would like to show the current exchange rate as on today for any currency in Dynamics Ax 2009 , then have a look in below steps.

I have developed DLL, which will interact with WebService to get the current exchange rate.
For illustration purpose i have taken example of "USD" to "INR" conversion.

Step 1 : Download the DLL , and copy to Dynamics AX Client Bin Folder
       
         2 : Add reference in AOT (Right Click Reference node and select Add Reference)
           Click on browse and select DLL which u copied in step1 and click Ok.
     
      3:  Refresh the client and copy the following job.

static void WebService_CurrencyConversion(Args _args)
{

    System.String exchRate;
    str           convRate;
    #Define.fromCurrency('USD')
    #Define.toCurrency('INR')
    ;

    new InteropPermission(InteropKind::ClrInterop);

    exchRate = WebServiceUtil.ServiceUtil::getExchRate(#fromCurrency, #toCurrency);

    convRate = exchRate;

    CodeAccessPermission::revertAssert();

    info(strfmt("1 %1 = %2 %3", #fromCurrency, convRate, #toCurrency));

}


Finally run this job and you will get the current exchange rate.  


You can use above logic and customize exchange rate form in Dynamics AX 2009  where the user can view exchange rate on that day.


Enjoy learning :)

New Feature , Type Hierarchies in Dynamics AX 2012

In DAX 2012 Developer workspace , you will find Type hierarchies under Tools menu which will list the hierarchy for the current object .
For more details please have a look in below video.

I know after watching this video , you will be eagerly waiting to work in next AX Version , 2012.

Dynamics Ax 2012 (AX 6.0) Developer WorkSpace

Have a look in new workspace mainly targeted for Development in Dynamics AX 2012.


Hope you will enjoy this new workspace !!!

Database upgrade in AX 6.0 or Dynamics Ax 2012

I came across nice blog on database upgrade in new version AX6.0 and other cool features , please don't miss this ,

http://blogs.msdn.com/b/mfp/archive/2011/01/21/getting-to-ax-2012.aspx

My main motive to share stuff about AX 6.0 is to make our self update with skills that will be going to use in new version when it hits market!!!

X++ CODE TO READ MS OFFICE WORD DOCUMENT

Use the below job if you want to read text from MS Word document in Dynamics Ax 2009.

static void FileIO_ReadFromWord(Args _args)
{     
        str         document = "D:\\Demo Edition.doc";
    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());
}

Integrate Google Map in Dynamics AX 2009

If you want to have feature for locating the customer/vendor addresses on Google map , than please have a look below ,

On Address form i have added a button Google Map , if clicked it will open Google Map inside AX!

For Having fun , select any record and change the address information and click on Google Map







Enjoy Learning AX !!!!

HOW TO USE STR VARIABLES IN SQL WHERE EXPRESSION, DAX 2009

I think most of us faced this issue , when we try to use str variable in X++ SQL statement like below

"Error: Container and unbounded string (text) fields are not allowed in a WHERE expression."


 
Because 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
 






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

X++ CODE TO GENERATE ALERT FOR RECORD IN DAX 2011

EventInbox and EventInboxData are two tables which will store the data related to alerts.
So one can easily generate alert by creating a record in EventInbox for xx user.
The problem with above approach is that alert will be triggered but if the user want to see for which record alert is triggered (by clicking on Go to Origin) than it will fail.

Always remember to make use of helper class  in DAX 2011 , whenever you want to use existing feature / functionality from standard product.

Following job illustrates how to use helper class EventNotification to generate alert  for InventTable record !

static void Event_sendAlertByCode(Args _args)
{

    EventNotificationSource _source;
    EventNotification       event = EventNotification::construct(EventNotificationSource::Sync);
    InventTable             inventTable;
    ;

    inventTable = InventTable::find('B-R14');  // sample record for which alert is shown

    event.parmRecord(inventTable);
    event.parmUserId(curuserid());      // user for which this alert to be shown
    event.parmDataSourceName('InventTable');  //form datasource
    event.parmMenuFunction(new MenuFunction('InventTable', MenuItemtype::Display));
    event.parmSubject('Test');
    event.parmMessage('Test Event alert');
    event.create();

}

When you run the above job , you can see alert for that user


Select the alert created above and click on Go to origin, then u will find record as,






By making use of helper class hardly we wrote 10 lines of code to accomplish the alert feature and thereby ensuring the quality of code, so always check twice for existing helper class before writing your own!!!!

Whats New in DYNAMICS AX 2012 OR AX 6.0 NEW COOL FEATURES

Wish you happy new year to you all and may you find always happiness in your life  :)

As you all know this year (2011) Microsoft is planning to release Dynamics Ax 2012 or famously called as Ax 6.0 .   So what we can expect in this new version , have a look below

1. Shift away from AOD files to a SQL Server-based model store, model files (.axmodel), the perception of "parallel layers" using models, the command-line utility AXutil to manage manage models and model files as well as the graphical Model Management tool for managing models and model files.

2. Setting up security in Microsoft Dynamics AX using the new role-based security model. wherein you will define the security artifacts in the AOT and creating security policies.

3. In Current version DAX 5.0 Configuration of Microsoft Dynamics AX2009 Role Centers and analysis cubes required a BI developer. In AX 6.0, setup and configuration of Analysis cubes can be done by a customer/partner with a wizard driven interface without having to go into BI development studio. 

4. New eventing feature will be available in Microsoft Dynamics AX,  it can be used to decouple publishers and subscribers, alleviating many upgrade issues.

5. Element IDs (such as table and class IDs) have been a problem since Microsoft Dynamics AX1 because they are limited to small ranges and often results in conflict between solutions. This, however, is changed in Microsoft Dynamics AX6. 

6. A lot of Workflow enhancements has been done in Ax 6.0 , wherein user will configure the workflow the way one creates flowchart in Visio.

7. Layout guidelines to support which language(X++ or .Net) or development environment (Visual studio or Morphx) to choose while doing customizations or developments.  So guys/gals please make yourself updated with C# development.

8. Tool available to Convert Reports developed in X++ to SSRS Report !!! And also the way used to deploy the SSRS Reports has been changed.

9. New enhanced X++ editor with lots of colored indentation , intellisense features and code formatting!!

10.  New Reporting programming model based on RDP which provides more controll over data and UI design.


Prepare yourself  to upgrade/development battle and enjoy new version once it reaches market !!!!

Add-ins to get the extended classes in DAX 2009

In AOT if you want to know for specific classes , what all child classes are extending this than have a look in following add-in .

Step1 : Create Job with following code.

static void TST_getExtendedClasses(Args _args)
{
    TreeNode        treeNode;
    SysDictClass    dictClass;
    List            extendedClassList;
    ListEnumerator  listEnumerator;
    SysContextMenu  contextMenu;
    Str             className, message;
    Counter         i;
    ;

    SysContextMenu::startedFrom(_args);

    contextMenu = _args.parmObject();
    treeNode    = contextMenu.first();


    i = contextMenu.selectionCount();

    if (treeNode.AOTparent().AOTname() == "Classes")  // Run only if it's opened from classes node
    {
        while (i >= 1)
        {

            dictClass           = new SysDictClass(className2Id(treeNode.AOTname()));
            extendedClassList   = dictClass.extendedBy();

            if (extendedClassList.elements())
            {
                listEnumerator = extendedClassList.getEnumerator();
                message = strfmt("Class %1 is extended by %2 subclasses.",treeNode.AOTname(),int2str(extendedClassList.elements()));
                setprefix(message);
                while (listEnumerator.moveNext())
                {
                    info(ClassId2Name(listEnumerator.current()));
                }

            }
            else
            {
                info(strfmt("Class %1 is not extended .",treeNode.AOTname()));
            }

            treeNode = contextMenu.next();
            i--;
        }
     }
}

Step2 : Create Menu Item with label as Get Extended classes and point to above job.

Step 3: Add above created menu item to the Menu 'SysContextMenu'.

Now if you do right click on class in AOT , than it should


When you select option Get Extended Classes , you will get the output as
Enjoyyy!!!!!!!!!

X++ Code to check the Invoice marked for settlement

Settlement feature allows you to select the open transactions(Vendor / customer)  and then you can post the payment journal for the same. I mean whenever you post PO or SO , all the payment details  will be sitting in Open transactions.
And these open transaction will be used latter for settlement , when you pay to the Vendor or receive the amount from customer.
Following Job illustrates how to check whether invoice is marked for settlement or not. The reason is if invoice is marked for settlement than those invoices cannot be used for posting in other journals.

For illustration i am using vendor invoices , second parameter (_buffer) should be ledgerJournalTrans , custTable or vendTable record for which you will be going to use the specified invoice.

boolean checkRecordMarked(InvoiceId _invoiceId, Common _buffer)
{

        boolean ret;
        ;
        select vendTransOpen
        join   vendTrans
        where  vendTransOpen.AccountNum == vendTrans.AccountNum &&
               vendTransOpen.RefRecId   == vendTrans.RecId      &&
               vendTrans.Invoice        == _invoiceId;


        specTransManager = SpecTransManager::construct(_buffer);
        ret = specTransManager.existForOtherSpec(vendTransOpen.company(), vendTransOpen.TableId, vendTransOpen.RecId);

        return ret;

}

X++ Code to Create Ledger and Inventory Journal names

Following job creates the journal names for all the different types of Journal type that have been defined in Ledger and  Inventory modules.
These journal names will be used for Posting Inventory and Ledger Journals in DAX.
 
void create_JournalNames()
    {
         
        LedgerJournalType     ledgerJournalType;
        LedgerJournalName   ledgerJournalName;
        Enumerator                  enumerator;
        DictEnum                     dictEnum;
        InventJournalName     inventJournalName;
        Counter                        i;
        InventItemType            inventItemType;
        InventJournalType       inventJournalType;
        str                                 itemTypeTxt;
        ;

        select firstonly numseqTable ;

        dictEnum = new DictEnum(enumnum(ledgerJournalType));

        // This block will loop until the end element of enum
        for (i=0;idictEnum.values();i++)
        {
            ledgerJournalType = str2enum(LedgerJournalType,dictEnum.value2Name(i));

            ledgerJournalName.clear();
            ledgerJournalName.initValue();

            ledgerJournalName.JournalName   = strfmt("%1%2_J",substr(enum2str(ledgerJournalType),1,3),i);
            ledgerJournalName.VoucherSeries = numseqTable.NumberSequence;
            ledgerJournalName.Name          = strfmt("%1 Journal",ledgerJournalType);
            ledgerJournalName.JournalType   = ledgerJournalType;

            if (ledgerJournalName.validateWrite())
                ledgerJournalName.insert();

        }

        dictEnum = new DictEnum(enumnum(inventJournalType));

        for (i=0;idictEnum.values();i++)
        {
            inventJournalType = str2enum(inventJournalType,dictEnum.value2Name(i));

            inventJournalName.clear();
            inventJournalName.initValue();

  
inventJournalName.JournalNameId   =strfmt("%1%2_J",substr(enum2str(inventJournalType),1,3),i);

            inventJournalName.Description     = strfmt("%1 Journal",inventJournalType);
            inventJournalName.JournalType     = inventJournalType;

            if (inventJournalName.validateWrite())
                inventJournalName.insert();

        }

    }

Enjoyyyy X++ Cooding !!!!!

Setup Email Alerts and X++ Code to Send Mail in DAX 2009.

Following steps illustrates how to setup and activate Email Alerts in DAX 2009.

In Ax we have two types of Alerts.
    1 ) Pop-Up Alerts , shown in AX Forms as pop-up windows.
    2 ) Email Alerts , where alert message will be sent to users by mail.  In other words its extended
         version of Pop-up Alerts.

How it Works :
   a ) For every alert ax creates record in SysOutgoingEmailTable and  
        SysOutgoingEmailData.
   b ) Then Email distributor batch(Class->SysEmailBatch->run method)  job reads the message
         from the above table and after validating execute the mail.

Now we will see what all setups are required for activating second type of alert.

Step1 : Activates the Alerts feature for user in options form .
             Go to  Tool-->Options  , set show email alerts  as


 Step 2 :  Set Email Parameters , Administration->Setup->Email Parameters
                 Define parameters like which SMTP  Server to use for sending mails and credentials
                 by which mail will be sent to users.




Step 3 : Add Email distributor batch to BatchJob Queue. This job will be responsible for sending mails to users. So if you are not receiving any email it means u have not scheduled this batch job to run.
             Administration->Periodic->Email-Processing--->Batch
Set the recurrence as No End date and minutes as 15-30 minutes.

Step 4 : Check the Batch Job queue for Email distributor batch job , you should find new record
               in batch queue as
               Basic-->Inquiries-->Batch Job
               For this record Click on Alerts and select check box "Error" . It means whenever this
               batch job fails you will get alert.

Incase of any failure you can debugg SysEmailBatch Class run method .

Step 5: Set up Email Templates and attach to EventParameters.
              Basic -> Setup -> Alerts -> Alert Parameter.

Step 6 :   Job to test whether u have configured correctly or not.
                  static void Mail_Send(Args _args)
                 {

                       EventParameters eventParameters = EventParameters::find();
                      SysUserInfo             sysUserInfo;
                     UserInfo                userInfo;
                     ;

                    // SysUserInfo has Alert and email info
                    sysUserInfo = SysUserInfo::find(curuserid());

                     // UserInfo has the language info
                    //userInfo = xUserInfo::find(false, eventRule.UserId);
                                         
 SysEmailTable::sendMail(eventParameters.AlertTemplateId,userInfo.Language,sysUserInfo.Email);

              
            

Even workflow framework uses same alert setups for sending mails for approval and task notifications.

Cool !!!!!!

Open doc , excel and Pdf in DAX 2009 Form

Hi,

I will be illustrating how we can load files like doc , excel and pdf on forms in Axapta 2009.
Advantages
      1.  You will have control on document like set rights for read only etc.
      2.  User will be in AX Workspace , no need for switching the windows between AX and Doc
           Viewer.

Steps  1.  Create form , add ActiveX Control of type Microsoft Web Browser in Design
            2.  Name the Control as CtrlActiveX
            3.  On Form Init Method , after super ()
                        CtrlActiveX.navigate("filePath");         // you can load URL for browsing

As show below in Image
When you run the form , you will see pdf inside form




Enjoyy File Viewing in DAX 2009.

X++ code to validate only numbers in string

Following job that illustrates how we can use regular expressions in axapta for validating only numbers in string.

static void TextBuffer_regularExpression(Args _args)
{

    TextBuffer txt = new TextBuffer();
    str msg = "98797897";
    ;


    txt.setText(msg);
    txt.regularExpressions(true);   // activate regular expr in search


     // Regular expression to validate only digits
     if (txt.find("^[0-9]+$"))
    {
        info("string contains only numbers");
    }

}

X++ Code to get the Ranges / Criteria from Query

Hi ,

Following Job illustrates how we can get the criteria / ranges specified by the user in the run-time Query criteria dialog.

static void Query_getRanges(Args _args)
{
    Query                   query = new Query();
    QueryRun                queryRun;
    QueryBuildDataSource    qbd;
    CustTable               custTable;
    QueryBuildRange         range;
    int                     cnt, i;
    ;

    qbd = query.addDataSource(tablenum(CustTable));

    queryRun = new QueryRun(query);

    queryRun.prompt();   // To Prompt the dialog

    cnt = queryRun.query().dataSourceTable(tablenum(CustTable)).rangeCount();

    for (i=1 ; i<=cnt; i++)
    {
        range = queryRun.query().dataSourceTable(tablenum(CustTable)).range(i);
        info(strfmt("Range Field %1, Value %2",range.AOTname(),range.value()));
    }

    while (queryRun.next())
    {
        custTable = queryRun.get(tablenum(CustTable));
        info(strfmt("Customer %1, Name %2",custTable.AccountNum, custTable.Name));
    }
}

Enjoyyy !!!!

X++ code to Count Records in Query

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)));
   
}

X++ code to Create Cue in DAX 2009

RoleCente's main purpose is to show various data on homepage which user will get to see all at a glance . Cue is also one among them .
Basically Cues in DAX 2009 are used for visual representation of data . In Technical terms Output of Query is represented graphically.

How Cue Works 
1. Open PurchTable form , click on advanced filter (Ctrl + F3)
2. Give any criteria ( status == Invoiced) and click on modify -->Save as Cue
 3. Save the Cue by assigning Cue Id as "Total_POInvoiced" , Security profile(who all can use)

4. Created Cue can be viewed in Basic-->Setup->RoleCenter->Edit Cues.



5. In order to deploy , Edit Role center homepage
             a. Click on Add new webPart and select Cues Web Part.
             b. Click on modify webpart and select above created Cue "Total_POInvoiced" in    
                 property      sheet .
             c. Click on Apply and Ok .
             d. When you exit edit mode , you will see total number of pending Invoices as image .

6. If you click on Cue "Total Invoiced PO " on Rolecenter you will be navigated to form which will show only invoiced purchase orders.

Technically :
When you create Cue , record gets created in CuesQuery Table with Formname , menuItemName and Query created from user criterias.
So when user click on Cue , It will take you to Form from where you created Cue by using the value from menuItemname.

Following X++ Job Creates Cue for customer form.

static void DEV_createCue(Args _args)
{
    CuesQuery       cuesQuery;
    Query           query = new Query(querystr(Cust));
    ;

    cuesQuery.clear();

    cuesQuery.CueId         = "TST_CustQuery2";
    cuesQuery.Caption       = "Cue test for CustTable";
    cuesQuery.CueVersion    = 1;
    cuesQuery.CreatorUserId = curUserid();
    cuesQuery.FormName      = "CustTable";
    cuesQuery.DataSourceName = "CustTable";
    cuesQuery.Query = query.pack();
    cuesQuery.ClientMenuItemName = "CustTable";
    cuesQuery.CueMin = 1;
    cuesQuery.CueMax = 10;
    cuesQuery.Threshold = 0;
    cuesQuery.ThresholdCriteria = CuesThresholdCriteria::None;
    cuesQuery.SecurityAccessFlag = CuesSecurityFlag::SpecifiedProfiles;
    cuesQuery.AdditionalValFunc = CuesAdditionalValFunc::None;
    cuesQuery.AdditionalValField = " ";
    cuesQuery.AdditionalValTable = " ";

    if (cuesQuery.validateWrite())
    {
        cuesQuery.insert();
        info(strfmt("Cue %1 Created with SecurityRights as %2",cuesQuery.CueId,cuesQuery.SecurityAccessFlag));
    }
}

Cool....

How to Create new Role Center in DAX 2009

Role center is  EnterPrise Portal Page which is used to show data , reports, pending activities and awaiting actions as per user role in the company.
Means whenever ax starts User will get homepage where he will see the data as per his role in the organization and can be personalized further to suit his requirements.
In order to have this feature available one should install and configure EP on his/her machine/server.
 After Installation do following steps,
  1.  Once you done with RoleCenter and EP installation ,
  2.  Go to Basic->Setup->RoleCenter-->Initialize Role Center will get some default profiles 
  3.  Admin-->Setup->User Profiles , click button Import and select from AOT
  4.  Default profiles (Role Centers) will be imported and You can start using by adding your userid to that select profile.
  5. Restart the AX Client and wait till default Home Page get load.

In Order to Create New RoleCenter in DAX 2009 , Have a look in following snap..

As shown in the figure, nodes under Develop the content are different components that are used to represent various data like SSRS Report , OLAP Cube for Data in BarChart etc.                      
It doesn't mean that all these are mandatory steps while creating new role center. For testing purpose just make use of Cue as specified in below image.

  Enjoy with your new role center !!!!!!!

View Embedded Resources in Ax

In DAX 2009 we have provision to view the existing resources like icons,images that are used on User Interfaces.
System will display all the resources with their Resource Id and image type. So whenever you want to display images and don't know the id then go for embedded resources as show in following snap.

Path : Tools-->Development tools-->Embedded Resource 

How to Install DAX on Stand alone Windows XP system

Unfortunately setup of AX on the computer outside a domain is prohibited by installer. But there is a trick for doing such thing and works good.
This trick is tested under Windows XP SP2, it does not work on Vista.

For Ax 4.0 Windows XP sp2 is required , for DAX 2009 Windows XP sp3 is required.

Here are steps of the trick (borrowed from AxForum):

1. Change the value of there registry key HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\ComputerName\ActiveComputerName to any value which does not match the name of your computer
2. Set value of environment variable named "UserDnsDomain" to any other value
3. Run setup.exe
4. Restore values, changed on the steps 1, 2
5. Go to client and server setup in control panel and change computer name to the real name of your computer

In order to install EP,Workflow for DAX 2009 on Windows XP we need to install share point services on Windows XP . Please visit the below link

Install SharePoint on WindowsXP


Enjoy installing DAX .........

X++ Class to Convert WebForm to Asp.net AX User control

As you all know from Version 5.0 EP development should be done in visual studio.
this means all the existing webforms developed in version 4.0 should be converted to asp.net ax user control.
This could have been taken care during the upgrade process , but unfortunately its not.

So please download the following class to convert the webforms to asp.net ax user control. this class has been developed by MS , but i don't know how come they have missed to include the same in AOT.
Not an issue , now you can do the same by downloading the following class.


Download SysEPWebFormConverter


Note Pre-requisite :
In order to test ,please create two webform named as WebForm1 and webForm2.
When you run the class you will find the new project containing converted asp.net ax user control in the project.

Enjoyyyyy!!!!!!.

UtilElements System Table , Objects usage log table in ax .

UtilElements stores the meta-data of all the AOT objects and even this table can also be used as log for tracking creation and modification of AOT objects.
And UtilElements is not RDBMS Table , whereas it uses filesystem to store data.

AOT Path for all system tables : \AOT\System Documentation\Tables\
Can be used for ..

1. To track the object creation and modification during development. i,e When you create a new or modify existing node in AOT , like table,field,report,index etc ax kernel creates/updates records in UtilElements table .

2. Even forms/reports accessed by the end-user can be tracked .

Limitation of this log table is we can't track the deleted objects in AOT.

So if you want to track who modified what object , this is the best place to look in.

X++ Code to Export AOT Object / automatic backup of xpo's.

we need to take daily backup of our development (interms of xpo) , but we all always forget becuase of our hectic work schedules.
So use the following job and build batch application to take backup of developement in terms of xpo .
We can take aod also but the size will be more and needs to stop AOS everytime .

Following job illustrates how to export/backup all AOT Classes object.

void DEV_ExportTreeNodeExample()
{

TreeNode treeNode;
FileIoPermission perm;

#define.ExportFile(@"c:\AOTclasses.xpo")
#define.ExportMode("w")
;

perm = new FileIoPermission(#ExportFile, #ExportMode);
if (perm == null)
{
return;
}

perm.assert();

treeNode = TreeNode::findNode(@"\Classes");
if (treeNode != null)
{

// BP deviation documented.
treeNode.treeNodeExport(#ExportFile);
}

CodeAccessPermission::revertAssert();
}

Enjoy !!!!!!!!

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;

}
}

For illustration i have used my own objects , So please test with your own valid objects.

Remove HTML Tags from String

Following Job illustrates how to strip htmltags from string.

static void Dev_StripHTML(Args _args)
{
Str htmlSource;
;

htmlSource = "Test" +
"HTML Tags Removed ";

info(Web::stripHTML(htmlSource));


}


X++ Code to Create Purchase Order and Post the Invoice.

Following Job creates the Purchase order from code and post the invoice by making use of PurchFormLetter class.
If you don't have demo data , please test with your input values.


static void Dev_CreatePO_and_Invoice(Args _args)
{

NumberSeq numberSeq;
Purchtable Purchtable;
PurchLine PurchLine;
PurchFormLetter purchFormLetter;

;

ttsbegin;
numberSeq = NumberSeq::newGetNumFromCode(purchParameters::numRefPurchaseOrderId().NumberSequence,true);

// Initialize Purchase order values
Purchtable.initValue();
Purchtable.PurchId = numberSeq.num();
Purchtable.OrderAccount = '3000';
Purchtable.initFromVendTable();

if (!Purchtable.validateWrite())
{
throw Exception::Error;
}
Purchtable.insert();

// Initialize Purchase Line items
PurchLine.PurchId = Purchtable.PurchId;
PurchLine.ItemId = 'B-R14';
PurchLine.createLine(true, true, true, true, true, false);
ttscommit;

purchFormLetter = purchFormLetter::construct(DocumentStatus::Invoice);
purchFormLetter.update(purchtable, // Purchase record Buffer
"Inv_"+purchTable.PurchId, // Invoice Number
systemdateget()); // Transaction date


if (PurchTable::find(purchTable.PurchId).DocumentStatus == DocumentStatus::Invoice)
{
info(strfmt("Posted invoiced journal for purchase order %1",purchTable.PurchId));
}
}

Change the documentstatus to packingSlip , if you want to post packing slip.
Enjoy ....Invoicing through Code.

TextBuffer Class to replace the special characters in string.

TextBuffer class can be used to replace the text/characters in the string.
Usually its used to replace the special character with escape sequence so that string(data with special character) can be inserted into the database.

Following job illustrates how to achieve this.

static void Dev_ReplaceTxt(Args _args)
{

TextBuffer buffer = new TextBuffer();
Str message;
;

message = " hi hello's how r u's ";
message += " How r u doing's wujer's * ? ' what ur mot's anbej's";

buffer.setText(message);
buffer.replace("[*?']","\\'"); // replace special character with escape sequence
info(buffer.getText());

}