Wednesday, 15 March 2017

Pass the parameter from one form to another in Dynamic AX

 Create two forms with Name FormA & FormB.

 FormA with 1 stringedit and 1 button & FormB with 1 StringEdit.

 Below code is override in clicked method() of button.

void clicked()
{
    // Args class is usually used in Axapta for passing parameters between forms
    Args            args;
    FormRun         formRun;
    ;
    args = new args();  
    // Our values which we want to pass to FormB
    // If we want pass just simple string we can use 'parm' method of 'Args' class
    args.parm( AccountNum.text() );
    // Run FormB
    args.name( formstr( FormB ) );
    formRun = classFactory.formRunClass( Args );
    formRun.init();
    formrun.run();
    formrun.wait();
    super();
}
 Now override init() method in FormB.
public void init()
{
    str             anyStringValueFromCaller;
    ;
    super();
    // Check for passed arguments
    if( element.args() )
    {
        // get string parameter
        anyStringValueFromCaller = element.args().parm();
        SelectedAccountNum.text(anyStringValueFromCaller);
    }
}

Monday, 20 February 2017

Working with utcDateTime in X++

The secret behind the capability of Dynamics AX to work flawlessly in different time zones is its utcDateTime data type. It combines date, TimeOfDay and time zone information into a single data type enabling the consultants to achieve date and time related requirements in a way that is more close to how we think about time in our daily lives. Like other data types in AX, utcDateTime can also be extended as required and used as the backing type of a database field.

Initialization

You can initialize a utcDateTime variable as follows.

transDateTime = utcDateTimeNull();
transDateTime = DateTimeUtil::utcNow();
transDateTime = DateTimeUtil::getSystemDateTime();

The utcNow method returns the current system time on the server without any time zone offset applied. Therefore the date/time returned by this method may not match the time you see on your machine.

The getSystemDateTime method returns the session date/time that could be set using the File > Tools > Session date and time dialog.

The newDateTime method instantiates date/time using the date, TimeOfDay and time zone parameters specified. The time zone offset when specified gets removed from the resulting date/time.

secondsElapsed = 14 * 60 * 60; // 02:00 PM
userTimeZone = DateTimeUtil::getUserPreferredTimeZone();
transDateTime = DateTimeUtil::newDateTime(today(), secondsElapsed);
transDateTime = DateTimeUtil::newDateTime(today(), secondsElapsed, userTimeZone);

Boundaries

The minimum value is 1900-01-01T00:00:00 and the maximum value is 2154-12-31T23:59:59. Note that the utcDateTimeNull function and the minvalue method return the same value.

transDateTime = DateTimeUtil::minvalue();
transDateTime = DateTimeUtil::maxvalue();

Date and time components

You can extract the date components (day, month, year) and time components (hour, minute, second) from a utcDateTime value as follows.

info(strFmt("%1", DateTimeUtil::date(transDateTime)));
info(int2str(DateTimeUtil::time(transDateTime)));
info(int2str(DateTimeUtil::day(transDateTime)));
info(int2str(DateTimeUtil::month(transDateTime)));
info(int2str(DateTimeUtil::year(transDateTime)));
info(int2str(DateTimeUtil::hour(transDateTime)));
info(int2str(DateTimeUtil::minute(transDateTime)));
info(int2str(DateTimeUtil::second(transDateTime)));

Manipulation of date and time components

You can add or subtract seconds, minutes, hours, days, months and years as follows.

transDateTime = DateTimeUtil::addSeconds(transDateTime, 60);
transDateTime = DateTimeUtil::addMinutes(transDateTime, 719);
transDateTime = DateTimeUtil::addHours(transDateTime, 36);
transDateTime = DateTimeUtil::addDays(transDateTime, 28);
transDateTime = DateTimeUtil::addMonths(transDateTime, 11);
transDateTime = DateTimeUtil::addYears(transDateTime, -1);
info(int642str(DateTimeUtil::getDifference(transDateTime, DateTimeUtil::minValue())));

The getDifference method returns the number of seconds between the two utcDateTime values specified.

Conversion

utcDateTime to str conversion can be done as follows.

dateTimeStr = DateTimeUtil::toStr(transDateTime);
dateTimeStr = DateTimeUtil::toFormattedStr(transDateTime, 231, DateDay::Digits2, DateSeparator::Hyphen, DateMonth::Short, DateSeparator::Hyphen, DateYear::Digits4, TimeSeparator::Colon, TimeSeparator::Colon, DateFlags::None);

The toStr method returns a string in the yyyy-mm-ddThh:mm:ss format, this is the format that X++ compiler recognizes.

The toFormattedStr method takes several parameters to control the formatting of date and time.

anytpe and str values can be converted to utcDateTime as follows.

transDateTime = DateTimeUtil::anyToDateTime(2015-07-03T23:45:30);
transDateTime = DateTimeUtil::parse("2015-07-04T00:00:00");

Calendar

User preferred calendar can be determined as follows.

calendar = DateTimeUtil::getUserPreferredCalendar();
info(enum2str(calendar));

Time zones

There are a several methods available in the DateTimeUtil class that can be used to work with time zones in AX. You can determine company time zone, user time zone and the client machine’s time zone.

entityTimeZone = DateTimeUtil::getCompanyTimeZone();
userTimeZone = DateTimeUtil::getUserPreferredTimeZone();
clientTimeZone = DateTimeUtil::getClientMachineTimeZone();
originTimeZone = DateTimeUtil::getOriginatingTimeZone(transDateTime);

The getOriginatingTimeZone method returns the time zone in which the specified UTC date time value was originated.

The getTimeZoneId method returns the standard time zone ID without mentioning the offset and city/country name e.g. PACIFIC STANDARD TIME.

info(DateTimeUtil::getTimeZoneId(entityTimeZone));

The getTimeZoneOffset method calculates the minute offset by subtracting time zone of the specified UTC date time (first parameter) from the specified time zone (second parameter).

info(int2str(DateTimeUtil::getTimeZoneOffset(DateTimeUtil::utcNow(), Timezone::GMTPLUS0500ISLAMABAD_KARACHI)));

The applyTimeZoneOffset method applies the specified time zone to the specified UTC date time value. This method is frequently used to apply user’s time zone to a UTC date time value previously stored.

transDateTime = DateTimeUtil::applyTimeZoneOffset(transDateTime, userTimeZone);

applyTimeZoneOffsetFilter

User preferred time zone offset can be applied to a filter as follows.

query = new Query();
dsRfqTable = query.addDataSource(tableNum(PurchRFQTable), 'Rfq');
dsRfqTable.addSelectionField(fieldNum(PurchRFQTable, RFQId));
dsRfqTable.addSelectionField(fieldNum(PurchRFQTable, VendAccount));
dsRfqLine = dsRfqTable.addDataSource(tableNum(PurchRFQLine), 'RfqLine');
dsRfqLine.addSelectionField(fieldNum(PurchRFQLine, ItemId));
dsRfqLine.addSelectionField(fieldNum(PurchRFQLine, ExpiryDateTime));
dsRfqLine.relations(true);
dsRfqLine.joinMode(JoinMode::OuterJoin);
filter = query.addQueryFilter(dsRfqLine, fieldStr(PurchRFQLine, ExpiryDateTime));
filter.value(queryValue(2015-07-15T00:30:00));
dateTimeStr = DateTimeUtil::applyTimeZoneOffsetFilter(filter);
filter.value(dateTimeStr);
info(dateTimeStr);

applyTimeZoneOffsetRange

User preferred time zone offset can be applied to a range as follows.

query = new Query();
dsRfqTable = query.addDataSource(tableNum(PurchRFQTable), 'Rfq');
dsRfqTable.addSelectionField(fieldNum(PurchRFQTable, RFQId));
dsRfqTable.addSelectionField(fieldNum(PurchRFQTable, VendAccount));
dsRfqLine = dsRfqTable.addDataSource(tableNum(PurchRFQLine), 'RfqLine');
dsRfqLine.addSelectionField(fieldNum(PurchRFQLine, ItemId));
dsRfqLine.addSelectionField(fieldNum(PurchRFQLine, ExpiryDateTime));
dsRfqLine.relations(true);
dsRfqLine.joinMode(JoinMode::OuterJoin);
range = dsRfqLine.addRange(fieldNum(PurchRFQLine, ExpiryDateTime));
range.value(queryValue(2015-07-31T01:30:00));
dateTimeStr = DateTimeUtil::applyTimeZoneOffsetRange(range);
range.value(dateTimeStr);
info(dateTimeStr);

If you need to query a table and filer the records such that only the records that were created/updated on a particular day are shown, you can use the datetobeginUtcDateTime and datetoendUtcDateTime methods. They take a date and time zone and returns the UTC date time when this date would begin/end.

transDateTime = datetobeginUtcDateTime(today(), userTimeZone);
transDateTime = datetoendUtcDateTime(today(), userTimeZone);

JOB:
static void Job23(Args _args)
{
    str s;
    TransDateTime       dt,dt2,dt3;
    date                date2,d = 7\8\1990;
    dt      = DateTimeUtil::utcNow();
    dt2     = DateTimeUtil::addYears(dt,3);
    date2     = DateTimeUtil::date(dt);
    info(strFmt("%1--%2--%3--%4",d,DateTimeUtil::utcNow(),dt2,date2));
//if (contract.parmBirthDate() > DateTimeUtil::date(DateTimeUtil::addYears(DateTimeUtil::utcNow(), -18)))

}

Friday, 9 December 2016

SSRS – No connection could be made

In a Microsoft Dynamics AX 2012 test system, I recently saw the following error when attempting to print any SSRS report:
No connection could be made because the target machine actively refused it
Error when creating SSRS report: No connection could be made because the target machine actively refused it
I confirmed that the relevant instance of SSRS was running, and decided that the problem was related to the port referred to in the error: 8203. I knew that this test AOS was the only one configured on this server and the default ports were being used – including 8201 for the Service port. I could not track down why port 8203 was being used.
After some help from Microsoft Support in Munich, the cause was found to be the Microsoft Dynamics AX configuration file that SSRS was using. The file is called Microsoft.Dynamics.AX.ReportConfiguration.axc and can be found in one of these locations (depending on the version of SQL being used).
If you are using SQL Server 2008: \Program Files\Microsoft SQL Server\MSRS10.[SSRSInstanceName]\Reporting Services\ReportServer\bin.
If you are using SQL Server 2008 R2: \Program Files\Microsoft SQL Server\MSRS10_50.[SSRSInstanceName]\Reporting Services\ReportServer\bin.
If you are using SQL Server 2012: \Program Files\Microsoft SQL Server\MSRS11.[SSRSInstanceName]\Reporting Services\ReportServer\bin.
The SSRSInstanceName can be found in AX at System Administration -> Setup -> Business intelligence -> Reporting Services -> Report servers in the ‘Server instance name’:
SSRS Report servers
SSRS Report servers
When I edited the Microsoft.Dynamics.AX.ReportConfiguration.axc file, I was able to search for several references to 8203:
AX Config file
AX Config file contains references to port 8203. The ports for the AOS and WSDL are also wrong.
I also noted that the ports for the AOS and WSDL were wrong.
Presumably, I could have corrected the information in the file. But the file is actually a standard AX client configuration file, and I simply replaced it with a copy of the .axc file I had been using to point the AX client at the test AOS. It would also have been possible to create this file using the AX 2012 Configuration Tool. After doing this, I was able to create SSRS output – a restart of the AOS or SSRS was not required.

Tuesday, 8 November 2016

TimeConsumed() function in ax 2012

timeConsumed()–a very useful function in Global class in AX 2012 [x++]

There is a very useful function timeConsumed() in Global class which we can use to calculate the time taken to execute business logic in AX 2012.

This function will return time consumed string in the form of X hours X minutes X seconds. If X is 0 – will not include the value + text.
It handles up to a 24 hour time difference not dependent on start/end time. If time consumed > 24 hours will only report time over 24 hour intervals.

Below is the example:

static void timeConsumed(Args _args)
{
    FromTime startTime = timeNow();
    int i;
    str dummyStr;
    ;
 
    for (i = 1 ; i <= 500000; i++)
    {
        dummyStr += int2str(i);  
    }
     
    info(strFmt("Total time consumed is  %1", timeConsumed(startTime, timeNow())));
}


static void Milliseconds(Args _args)
{
    TimeInMS        startTime,endTime;
    int i;
    str dummyStr;
    ;
    startTime = WinAPI::getTickCount();

    for (i = 1 ; i <= 500000; i++)
    {
    dummyStr += int2str(i);
    }
    endTime = WinAPI::getTickCount();
    info(strfmt("%1 Milliseconds",endTime-startTime));
}

Monday, 19 September 2016

Restrict multiple times user login in AX 2012

Currently in Ax 2012 the user can login  multiple times in application, so to restrict users to open Ax 2012  multiple times we can use the following code.
---->Before implementing this please take backup of your application files
Open Classes --> info --> StartupPost metod
and copy following code into this method

void startupPost()
{// To restrict user login form second login
    xSession                    session;
    SysClientSessions           sysClientSessions;
    UserId                      currentUserId;
    int                         counter;  
    ;

    if(curUserId()!="Admin")
    {
        while select SysClientSessions
            where SysClientSessions.userId == curUserId()
                && SysClientSessions.Status == 1                  // 1 : Login 0 : Logout
                && SysClientSessions.sessionType == 0       //  sysClientSessions.clientType == 0
        {
            session = new xSession(SysClientSessions.SessionId, true);
            if (session && session.userId())
            {
                counter++;
            }
        }
        if(counter>=2)
        {
            Box::stop("Already Logged-in : The same user id can't log in twice.");
            infolog.shutDown(true);
        }
    }

}

http://daynamicsaxaptatutorials.blogspot.in/2011/04/restrict-multiple-user-login-in-axapta.html

https://dynamicsuser.net/ax/f/technical/68340/user-permissions-in-ax2009-to-be-able-to-send-an-e-mail

http://archive.bottomline.com/collateral/technical_documents/TN10%20Microsoft%20Dynamics%20AX%20Connector%20User%20Security%20Permissions.pdf


Monday, 4 July 2016

Table Inheritance In Microsoft Dynamics Ax 2012

When you consider the use of inheritance between two tables, one table is the proposed base table, and the other is the proposed derived table.

should consider the use of inheritance between two tables when all the following conditions are true:

   1) There is no thought that there might be a 1-to-many or many-to-many relationship between the two tables.

    An existing row in the proposed base table, and the corresponding row in the derived table, both refer to the same item in the real world.

    Each row in the proposed base table has exactly one corresponding row in the derived table.

    If one row is ever deleted from either table, the corresponding row must also be deleted.

    The base table probably has at least two tables that derive from it.

    The two derived tables have fields for different kinds of things.
    The two derived tables refer to different variations of the general items that are tracked together in the base table.

    No item that is represented in a base table would ever be represented in more than one of its derived tables.

    The derived table is not meant for performance tuning of the physical database, such as placing an image column in its own table.

Example:
Create a table and name it as Base table.
[Note: For a temporary table ,we cannot set the support inheritance property to YES.]

create a field with datatype int64 and name it as InstanceRelationType.

Now set the Table property Support Inheritance --> Yes

create a field with datatype int64 and name it as InstanceRelationType.
create a field  with datatype str and name it as person.
create one more field with datatype int and name it as MyID.
Now set the table properties:

InstanceRelation Type --> InstanceRelationType
Abstract --> Yes

Create a new table and name it as Derived table.

set the table properties
Support Inheritance --> Yes
extends to -->BaseTable

create one more table and name it as Derived.

set the table properties
Support Inheritance --> Yes
extends to -->BaseTable

create a field with datatype str and name it ContactNo.

Now we will get the fields automatically in the Derived table.
Links: