Tuesday 29 April 2014

SysServerSessions and SysClientSessions are missing in the Ax 2009 database

Issues:- 1.Object Server 04: The database reported (session 2 (-AOS-)): [Microsoft][ODBC Driver Manager] Connection not open. The SQL statement was: "select  DATEPART(d,  GETUTCDATE()),         DATEPART(m,  GETUTCDATE()),    
  DATEPART(yy, GETUTCDATE()),         DATEPART(hh, GETUTCDATE()),         DATEPART(n,  GETUTCDATE()),         DATEPART(s,  GETUTCDATE())"

2.Object Server 04: Fatal SQL condition during login. Error message: "[Microsoft][SQL Native Client]Login timeout expired"

3. Object Server 04: Dialog issued for client-less session 1: Cannot select a record in Current AOS instances (SysServerSessions). ServerId: 0, .
Error accessing database connection.

Resolve:- Check your database in single user mode  make it multi user ->right click on the data base -> properties->select options->down you will find -> Restrict actions->change it multi user mode.
and
  you can resolve like
http://daxdilip.blogspot.in/2009/02/sysserversessions-and-sysclientsessions.html

Thursday 24 April 2014

Email techniques in AX 5.0

In this article, I am going to demonstrate different email techniques that can be used in AX 4.0. Following classes can be used to send an email

Configure the SMTP server 

http://www.vsysad.com/2014/01/configure-iis-smtp-server-to-use-gmail-to-forward-messages/

http://gaurangpatel.net/setting-up-smtp-server-in-windows-to-use-gmail

https://fmuntean.wordpress.com/2008/10/26/how-to-configure-iis-smtp-server-to-forward-emails-using-a-gmail-account/


http://www.blackbaudknowhow.com/tech-tips/how-to-install-and-configure-smtp.htm

  • Mapi and its related classes
  • SysMailer
  • SysInetMail
  • SysEmailBatch
  • SmmOutlookEmail
SysEmailBatch:
SysEmailBatch internally uses SysMailer class and is used to send emails in batch. That is this class is batchable. Here is a small example for the class
static void emailThruSysEmailBatch(Args _args)
{
    SysEmailBatch   batch = new SysEmailBatch();
    ;

    batch.parmSenderAddr("aslam.p@XYS.net");
    batch.parmEmailAddr("aslam.p@p@XYS.net");
    batch.parmMessageBody("Hi There");
    batch.parmSubject("Test mail");
    batch.run();
    info('Done');
}


SysMailer:
In the following code you can see how to use SysMailer class for sending mails. To use SysMailer class you need to set Relay server or computer name, user name and password in Administration –> Setup –> Email parameters form. This class internally uses CDO.Message dll for communication purposes. Please note in AX 3.0 SysMailer uses Dundas.Mailer dll for communication.
static void emailThruSysMailer(Args _args)
{
    SysMailer   mailer = new SysMailer();
    SysEmailParameters parameters = SysEmailParameters::find();
    ;

    if (parameters.SMTPRelayServerName)
    {
        mailer.SMTPRelayServer(parameters.SMTPRelayServerName,
                           parameters.SMTPPortNumber,
                           parameters.SMTPUserName,
                           SysEmailParameters::password(),
                           parameters.NTLM);
    }
    else
    {
        mailer.SMTPRelayServer(parameters.SMTPServerIPAddress,
                           parameters.SMTPPortNumber,
                           parameters.SMTPUserName,
                           SysEmailParameters::password(),
                           parameters.NTLM);
    }

    mailer.fromAddress("aslam.p@XYZ.net");
    mailer.tos().appendAddress("aslam.p@XYZ.net");
   // mailer.body("hi");
    mailer.sendMail();
    info('Done');
}
static void Email(Args _args)
{
    str ToAddress =  "aslam.p@infotech.net";
    str FromAddress = "aslam.p@infotech.net";
    str Subject = "Journal not posted";
    str Body ;
    str FileToAttach = 'C:\\Users\\aslam.p\\Desktop\\Report AX 2012, data processing_files\\A.Txt';//
    SysMailer  mailer = new SysMailer();
    ;
    Body = "<B>Body of the email</B>";
    mailer.quickSend(fromaddress,toaddress,subject,body,toaddress,FileToAttach);
    info("Done");
}
static void EmailsendwithAttachment(Args _args)
{
    Args args;
    ReportRun rr;
    str reportName = "Report2";
    str myPath,pdfFileName;
    str ToAddress =  "aslam.p@infotech.net";
    str FromAddress = "aslam.p@infotech.net";
    str Subject = "Journal not posted";
    str Body,messageBody ;
    SysMailer  mailer = new SysMailer();
    ;
    messageBody = "<p>Dear All,</p><P> Please find the errors in ledger journal report attached.</p>";
    messageBody += "<p><font size=3 face=Garamond>Regards,</font></p><p><strong><font size=3 face=Garamond>AX Admin</font></strong></p>";
    messageBody += "<p><strong><font size=3 face=Garamond>Microsoft Dynamics AX</font></strong></p>";
    messageBody += "<p><strong><font color=#808080 size=3 face=Tahoma>Hospital</font></strong></p>";
    body = strfmt("%1",messageBody);
    startLengthyOperation();
        args = new Args(reportName);
        args.caller(rr);
        rr = new reportRun(args);
        rr.query().interactive(false);
        rr.report().interactive(false);
        rr.setTarget(printMedium::File);
        rr.printJobSettings().setTarget(PrintMedium::File);
        rr.printJobSettings().preferredTarget(PrintMedium::File);
        rr.printJobSettings().format(PrintFormat::PDF);
        rr.printJobSettings().warnIfFileExists(false);
        rr.printJobSettings().suppressScalingMessage(true);
        pdfFileName = @"C:\\Users\\aslam.p\\Desktop\\Report1.pdf";
        rr.printJobSettings().fileName(pdfFileName);
        rr.init();
        rr.run();
    endLengthyOperation();
    info("Report hasbeen saved");
    mailer.quickSend(fromaddress,toaddress,subject,body,toaddress,pdfFileName);
    info("Done");

}
static void email(Args _args)
{
    // For email notification
    str                         messageBody;
    NWH_XmlImpErrorFlag         XmlImpErrorFlag;
    InteropPermission           permission = new InteropPermission(InteropKind::ComInterop);
    SysMailer                   mailer;
    str                         Body;
    str                         ToAddress;
    str                         FromAddress = "aslam.pasha@infotech.net";
    str                         Subject = "Integration Alerts";
    int                         x;
    H_IntegrationParameters   parameters;
    Container                   id;
    LedgerJournalTrans          ljt;
    date                        checkdate;
    Real                        CheckDr , CheckCr ;
    int i,j;
    ;
    try
    {
       info("In the 'try' block. (j1)");
       info("infolog!");
       throw warning("test warning");
       throw error("test error");
       info("infolog!");
       throw warning("test warning");
        //throw Exception::Error;
    }
    catch
    {

        for (i=1; i<=infolog.line(); i++)
        {
            messageBody = ":" + infolog.text(i);

        }
        parameters = H_IntegrationParameters::find();
        id = str2con(parameters.HSEmailId,",");
        for(x=1 ; x <= conlen(id); x++  )
        {
            toaddress   =  strRem(conpeek(id,x)," ");
            Body = strfmt("%1", messageBody) ;
            CodeAccessPermission::revertAssert();
            permission.assert();
            mailer = new SysMailer();
           // CodeAccessPermission::revertAssert();
            mailer.quickSend(fromaddress,toaddress,subject,Body);
        }

    }
}
void NormalEmailSend()
{
    str FromAddress =  "XYZ.p@test.net";
    str  ToAddress = "XYZ.p@test.net,XYu.p@test.net";
    str Subject = "Journals Posted successfully";
    str Body,messageBody ;
    SysMailer  mailer = new SysMailer();
    ;
    messageBody = "<p>Dear All,</p><P> All journal has been posted successfully.</p>";
    messageBody += "<p><font size=3 face=Garamond>Regards,</font></p><p><strong><font size=3 face=Garamond>AX Admin</font></strong></p>";
    messageBody += "<p><strong><font size=3 face=Garamond>Microsoft Dynamics AX</font></strong></p>";
    messageBody += "<p><strong><font color=#808080 size=3 face=Tahoma>Women's </font></strong></p>";
    body = strfmt("%1",messageBody);
    mailer.quickSend(fromaddress,toaddress,subject,body,toaddress);
    info("Normal Email send -Done");
}

https://sumitsaxfactor.wordpress.com/2008/09/09/email-techniques-in-ax-4-0/ 

Wednesday 23 April 2014

Breakdown of a list page (Sales orders)

http://axinternals.blogspot.in/2011/09/breakdown-of-list-page-sales-orders.html

AX 2012 Override method of ActionTab buttons for ListPage Forms like CustTableListPage

http://asifhuddani.wordpress.com/2011/10/19/ax-2012-overwrite-click-method-action-tab/

Changing color of records/Individual fields based on flag in AX

Changing color of records/Individual fields based on flag in AX
The below code will provide different colors for different records in salestable form based on salesstatus enum..
public void displayOption(Common _record, FormRowDisplayOption _options)
{
    SalesTable prodtablelocal;
    prodtablelocal = _record;
    Switch(prodtablelocal.SalesStatus)
    {
        Case SalesStatus::Delivered:
        _options.backColor(65535); //Light Yellow
        //_options.affectedElementsByControl(Salestable_SalesId.id());
        Break;
        Case SalesStatus::Invoiced:
        _options.backColor(8421631); //Light Red
        //_options.affectedElementsByControl(Salestable_SalesId.id());
        Break;
        Case SalesStatus::Backorder:
        _options.backColor(65408); //Light Green
        //_options.affectedElementsByControl(Salestable_SalesId.id());
        _options.textColor(12582912);
        Break;
    }
}
The below code will provide different colors for (only for selected fields) salesid field for a record in salestable form based on sales status enum.. this is done by uncommenting the _options.affectedElementsByControl(Salestable_SalesId.id());
lines.
In the same way, you can add different fields by setting autodecalaration to ‘Yes’ in design for respective fields in design > control names from the form.
public void displayOption(Common _record, FormRowDisplayOption _options)
{
    SalesTable prodtablelocal;
    prodtablelocal = _record;
    Switch(prodtablelocal.SalesStatus)
        {
        Case SalesStatus::Delivered:
        _options.backColor(65535); //Light Yellow
        _options.affectedElementsByControl(Salestable_SalesId.id());
        Break;
        Case SalesStatus::Invoiced:
        _options.backColor(8421631); //Light Red
        _options.affectedElementsByControl(Salestable_SalesId.id());
        Break;
        Case SalesStatus::Backorder:
        _options.backColor(65408); //Light Green
        _options.affectedElementsByControl(Salestable_SalesId.id());
        _options.textColor(12582912);
        Break;
    }
}

How to colorize Rows In Grid With Different colors using X++ in AX 2009?
You need in sometimes to colorize specific rows with different color to do anything in your business rules to do this :
1-  Go to the data source of  your form
2- Choose that data source is used by the grid that you want to color it
3- write click on the override method and select displayOption  method and put the following code inside
public void displayOption(Common _record, FormRowDisplayOption _options)
{
    if (_record.(fieldnum(MBST_PAYMENTS_HDR,POST_FLAG))=="YES")
    {
        _options.backColor(WinAPI::RGB2int(161,161,255));
    }
    super(_record, _options);
}
Changing Form color based on the current Company

Basically you override the SysSetupFormRun.run() method. Below is some sample code:
public void run()
{
    ;
    super();
    // Set the color scheme of this instance of te SysFormRUn to RGB
    this.design().colorScheme(FormColorScheme::RGB);
    // Switch and based on the current company change colors, or not for default
    switch (curext())
    {
        case 'DEM':
        this.design().backgroundColor(WinAPI::navisionColorRed());
        break;
        case 'dat':
        this.design().backgroundColor(WinAPI::navisionColorBeige());
        break;
        default:
        break;
    }
}
Now when you switch between the two companies and launch a form, you will see visually, that you are in a different company. Granted the WinAPI::navisionColorBeige(), ..Blue(), ..Red() are not that great looking, but still you get the idea. And if
you know RGB colors, then you can supply really any valid RGB color you like!
Anyway this is a neat little trick that is ran each time a new instance of a given form (other that the main menu) is ran. 
http://daxguy.blogspot.in/2007/04/coloring-grids-in-dax.html

Monday 21 April 2014

FetchIpAddress From ax through X++ ax 2009

static void FetchIpAddress (Args _args)
{
System.String                       hostName = System.Net.Dns::GetHostName();
System.Net.IPHostEntry              hostEntry = System.Net.Dns::GetHostEntry(hostName);
System.Net.IPAddress[]              addresses = hostEntry.get_AddressList();
System.Net.IPAddress                address;
System.Net.Sockets.AddressFamily    addressFamily;
System.Collections.IEnumerator      enumerator = addresses.GetEnumerator();

while (enumerator.MoveNext())
{
    address = enumerator.get_Current();
    addressFamily = address.get_AddressFamily();
    if (addressFamily == System.Net.Sockets.AddressFamily::InterNetwork)
    {
        info(address.ToString());
    }
}
}

Sunday 13 April 2014

Query_getRanges in ax 2009

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