Saturday, December 31, 2011

DateSeparator: What's missing in the documentation of date2Str

The function date2Str provides a good way to convert a date to a string in Dynamics Ax.
The string output can be controlled, you can specify the notation with different parameters.
It goes something like this:

   str date2Str(
    date date,
    int sequence,
    int day,
    int separator1,
    int month,
    int separator2,
    int year
    [, int flags = DateFlags::None])


In an example:

static void Example_date2str(Args _args)
{   ;
    info(date2str(systemdateget(),123,2,1,2,1,4));
}


But the documentation lacks a bit of details around the different separators to use.



The different options are all listed here, but the actual values to use in the date2Str function are omitted.  The function requires an integer (or enum) as parameter for the date separator.
And not a char or string, like "/" or "-".
You can use the enum DateSeparator for this.  This enum has following enumerations:

NameValueDescription
Auto99Auto
None0None
Space1
Dot2.
Hyphen3-
Slash4/

This part of the documentation got updated with the newly released Ax 2012 version.  So the missing info only applies to versions 3.0, 4.0 and 2009.  (Like you can find both in Ax help system - see screendump above- or online at MSDN over here.)
Same example as above, but less cryptic:

static void Example_date2str(Args _args)
{   ;
    info(date2str(systemdateget(),
        123,
        dateDay::Digits2,
        DateSeparator::Space,
        DateMonth::Digits2,
        DateSeparator::Space,
        DateYear::Digits4));
}

Good to note here as well is that there is another way of setting the notation: Use the regional settings of the user.
For that, just set all the formatting parameters to -1.

Like this:

static void Example_date2str(Args _args)
{   ;
    info(date2str(systemdateget(),-1,-1,-1,-1,-1,-1));
}

Dynamics Ax actually has a predefined function for this in the Global class, being date2StrUsr.
static void Example_date2str(Args _args)
{   ;
    info(date2strUsr(systemdateget()));
}

This function depends on date2Str, just like in the example above.  From the Ax source code:
static TempStr date2StrUsr(date transDate,int flags = DateFlags::None)
{
    return date2str(transDate,-1,-1,-1,-1,-1,-1,flags);
}

Monday, December 26, 2011

Happy New Year!

Thanx for reading my blog, now and in the future.  Wishing you all the best for 2012.

Best wishes for 2012
A big thank you for the nice comments as well!

Dynamics Ax and the cloud - Part 2

In the last blog post we talked about Dynamics Ax and the cloud.  And the fact that Microsoft's latest release of Dynamics Ax, Ax 2012, is not the cloud version (some hoped for).  Is it a sign?  Should we be unhappy about that?



Microsoft already has some cloud solutions up and running, focussed on business users.  With Office 365, CRM 2011 for example.   With  varying degrees of success, on all levels.
Take availibility for example: Customers of Microsoft’s Business Productivity Online Services (BPOS), with hosted Exchange and Sharepoint solutions, had to work without mail for a few days after a MS upgrade mid 2011.  In August 2011, it was MS CRM 2011 and Office 365 which suffered from outages. And again.
Every IT department has to deal with downtime one time or another.  But when an IT department serves thousands of customers with an online solution, it's high profile, big news.  And Microsoft can hopefully learn from these experiences and improve them, for an Ax cloud release later.

Another level where Microsoft has not reached the desired success (yet) is the propagation of their cloud solution platform.
Microsoft Azure platform has been around for some time now.  And strangely enough, the critics are more or less aligned on this one: A good solid offering, but MS did a bad job on marketing it.  And that's strange for a company like MS, as that has always been one of their key strengths in the past.

But it should be clear that even with recent takeovers from competitors SAP and Oracle this does not mean that Microsoft is running behind, on the contrary.  Microsoft has put its pawns on the chessboard and is (almost) ready to play.

And what about any other players than the big three? 

Google, the household name when it comes to the cloud, isn't free from glitches either.  It would also be interesting to see if they can increase the acceptance of their business solutions with business users as well.  Google depends heavily on their advertising model.  For that, they go through everything you do on the internet: all your searches, all your mail, ...
How is Google going to convince companies that their business critical data is stored safe with them?

Maybe the real threat comes from another familiar name, albeit maybe a bit unexpected here: Amazon.
Amazon, still a relatively young company, made it from an online book store to a software company.
While Amazon did not escape the run of outages in 2011, at least they communicated clearly about them.  Always.
They seem to understand the need of information of the users in such cases, in order to uphold confidence of the community in their solution.

When Denmark based ProISV, a software developer focussed on ISV's (Independent Software Vendors), released their Ax Cloud solution, they made the link with Amazon.  (Betting on two horses actually, as they also work with MS Azure.)

Maybe IBM can become an important player here.  They have the servers and infrastructure experience, they have made the transition to a services company as well.

Conclusion
The software business is on the move, to the cloud.  We gonna see lots of announcements and news stories focussing on ERP in the cloud in 2012, without doubt. 
As details of the next major release of Dynamics Ax (version 7.0, post Ax 2012) will gradually become available in 2012, it will also be exciting times for Ax customers.

Saturday, December 10, 2011

Did Dynamics Ax already make it to the cloud?

SAP is the latest to jump on the cloud bandwagon with their aquisition of SuccessFactors, an established player in cloud offerings.  First weekend of December 2011 it was announced that the deal was worth $3.4 billion, not a minor expense.  Last October we saw this other big ERP player Oracle buy RightNow for $ 1.5 billion.  Earlier in October, Oracle unveiled Oracle Public Cloud. That's when they publicly entered the cloud arena, with an 'Enterprise cloud for your business' as Oracle states it.
You can argue whether they are all just hosting solutions or real cloud solutions.  But it's clear these contenders are more then willing to link their corporate names to the cloud.  Cloud isn't about consumers anymore, it's also about enterprises.

And what about Microsoft?  And Dynamics?  Where are they?

Well with Dynamics CRM 2011 already has a cloud offering for one member of the Dynamics family of products. When it was released January 2011 the online features were a key selling point.
Dynamics NAV 7 has been postponed once or twice.  Currently slated for Fall 2012, it expects to be  run on the Azure platform.  And the client to be a webbrowser, whether NAV is running on premise or in the cloud.

At Convergence 2011 in Atlanta, Steve Ballmer already announced all members of the Dynamics family are or will be engineered to "deliver the full benefits of the cloud".  And that's with focus on Azure, Microsoft's cloud development platform.

And the recently released Dynamics Ax 2012, is that a cloud version?  The answer is 'no'. 
During the virtual launch event in August 2011 Hal Howard, corporate VP of ERP at Microsoft, already stated that Ax 7, not AX 6 will be the first real Ax cloud offering.  He repeated that statement in his keynote at the Dynamics Ax 2011 Technical Conference in Nice. 
So Ax is not the first, not even the second to make it to the cloud.

Should Ax customers and MS partners be unhappy about that?  More about that in the next blog post.

Tuesday, November 29, 2011

Error: Cannot create another system semaphore

When trying to start the Dynamics Ax AOS service, the attempt fails.
You may receive following error message:

Error: Cannot create another system semaphore

When you check the Windows event log, you may come across following error:

Fatal SQL condition during login.

Probable causes:

  1. The SQL Server service is down, verify this first.
  2. The account that has been setup to start the AOS service, does not have the proper security rights for the Ax SQL database.
Regarding number 2:
If you copy your database from one environment to another (from Production to Test for example), make sure you have the right security setup in place.  Does the startup account used for the AOS service have access to the SQL database?

Once the account has access, make sure it has proper access.
If you don't want to give it the db_owner role, make sure at least following roles are assigned to the service account

• db_ddladmin
• db_datareader
• db_datawriter




Also make sure permission to execute both stored procedures is in place.



After you verified the above, you should be able to start the AOS service.

Monday, November 28, 2011

What's wrong with the audience?

When doing development/debugging/troubleshooting, you come across the strangest things.  Error messages that don't give you the slightest idea on what's happening, or just funny ones.  Like this message from the Windows event log I found amusing:


Failed to compile audience.

Compile the audience, a whole new approach for your presentations.
The message is from SharePoint server by the way.

Friday, November 25, 2011

A touch of Dynamics Ax

One of the more interesting features of the latest version of Dynamics Ax, where I had high expectations, were the touch enabled features in the production area.
During last week's Technical Conference in Nice,  we saw a nice build up towards the demo of Manufacturing Execution, the new name of the Shop Floor module.
  • During one of the keynotes the unique position of Microsoft was highlighted.  It's the only vendor in the market that serves both consumers and businesses.  Imagine the experiences those teams can share?
    Touch screens for mobile phones are more than common these days.  We see an increase in touch functions for standard PC's with each release of Windows.  These developers of Microsoft must have tons and tons of experience with touch driven solutions.  Touch enabled features seem like an obvious thing today.  Can you imagine Windows Mango without touch?
  • Key note speakers talked about Dynamics Ax and the use of Kinect, control Ax with gestures.  There exists a software development kit, Kinect is coming to the PC.  So yes, why not bringing it on to the business floor, the ShopFloor?  Already the next step.
  • If you look at the user interface of Dynamics Ax Retail, you can't help but notice it has touch enabled features all over the place.  It's very clear what the developers had in mind when working on it.



The intro of the session was promising, as we were being introduced to the configuration of the terminal screens.   You can do some customizations there, defining different kind of terminals, configure the form layout (without developing).  Stuff like enable/disable close actions, the action pane etc.

We saw a numeric keypad, with the big buttons, and...  that was it.  Touch features ended right there.

The layout of the other forms was totally not touch oriented.  The processes were in no way adapted to the specific needs of touch.
If I see the use of the scrollbars, the way dropdown fields are used, the build up of the grid, ... Without mouse and keyboard, you are lost.

I've been working with Dynamics Ax on the production floor for almost 10 years now, making touch enabled input screens.  Customizing some interfaces or creating new ones, adapting the flow of data entry to what machine operators need.   I know when it works and even more when it doesn't work and this... 

I really hoped we would be getting something out of the box, ready to be deployed at a machine near us but no such luck.
The speaker tried to save the day, by saying stuff like 'you can always increase the font size' to set the grid height.  But he knew he wasn't very convincing.
Sorry to say, but the guys working on Ax 2012 in the production area didn't get 'touch'.  Microsoft really missed a chance here.
Still plenty of room for partners to bring in there solutions though.

But to end of with a positive note: You don't pay full price for an ME client.

Monday, November 21, 2011

myAx - a mini version of Dynamics Ax

At the end of keynote 3 at the Dynamics Ax Technical Conference 2011 in Nice, some time was reserved for Q & A.
Interesting question popped up:

Q  Is there a mini Ax version planned, for smaller companies?

I consider this question very relevant.
With each major release of Dynamics Ax, we see an increase in functionality, an increase in complexity.  Despite all the effort that goes into simplifying things: Simplifying both everyday working for users as well as implementing the solution for partners.
When more functionality is introduced, you basically introduce more possibilities. But that comes with a price.
And yes, we have RapidStart Services now.  But that's no magic wand.
You can clearly see that Microsoft positions Ax higher and higher in the market, aiming for more customers with +1000 users.  Maybe in a 2-tier setup, but if Ax is the core ERP system of the customer company that's even better.

Kees Hertogh, Director Product Management, took it upon him to answer the question and he did that very clearly.

A  No, there is no mini Ax version planned.

Don't expect anything like that either. 
"And yes, we know there exists something like mySAP, but that's not really for small companies."
His advice was equally clear:
"If you fear Ax is a too big of a bet for your company, you should consider Dynamics NAV instead."

Saturday, November 19, 2011

Cumulative update 2 for Dynamics Ax 2012 released

Even with launch events still going on all over the world, Microsoft already released cumulative update number 2 for Dynamics Ax 2012.
70+ fixes are included in the update.  RapidStart issues, performance issues with the GAB, workflow, client crashes, ... Something for everyone it seems.
This update of course includes the fixes included in update 1, that's why they call it cumulative :-)
More information can be found on the support website, over here.

Friday, November 18, 2011

NUMB3RS

The Dynamics Ax Technical Conference 2011 was all about Dynamics Ax 2012, internal version number 6.0.  Microsoft is finishing up work on the next version being 6.1, to be released Q1 of 2012.  This will include the Retail offering.  And the people of Redmond talk vividly about 6.2 or V-Next already, to be expected in 2013.  And then there's version 7.0 on the roadmap as well...

Wednesday, November 16, 2011

Nice was nice

The last slide of the last PowerPoint presentation has been shown.  The banners can be stored for a future event.
The Dynamics Ax Technical Conference 2011  has come to an end.  Lots of things learnt, exciting stuff happening, a lot to share.  Expect some bits and pieces over the next few days over on this blog. (and lots of other blogs I imagine)

Very trivial, but one of my observations to start with:

If you attend a presentation and you don't take pictures with your mobile device (be it a phone, iPad, slate, ...) of the slides shown, you belong to a minority.  Now there's some food for thought that in 2011, we have this crazy mix of digital and analog information storing.  And what a contrast with the cool video at the end of Hal Howard's keynote on day 1, showing a possible future.  Seems such a long way to go then.

Edit: Even mfp does it!

Monday, November 14, 2011

Are you crazy or ...?

A beautiful city in the south of France, at the Côte d'Azur
Relaxing temperatures, a ray of sunlight through the palm trees


And 800 people locked inside an auditorium with all the windows blinded
There must be a tech convention going on...

It's the Dynamics Ax Technical Conference 2011 at the Acropolis in Nice!

Some excellent conditions to make this a great success. But the Demo Gods are not with us...
Already saw a Visual Studio crashing, an AOS server reluctant to start up.  But other than that some good informative sessions. Answering some questions, but also bringing more to mind...
More to follow.

Wednesday, October 12, 2011

What about 'The command-line parameter -compressionminsize=1024 is invalid.' error message?

When starting the Ax client by clicking an Ax configuration file (.AXC), you may receive following error message:

The command-line parameter -compressionminsize=1024 is invalid.
Check the spelling and start Microsoft Dynamics AX again.




Possible cause, and a solution:
You are using an Ax configuration file to start Ax.  But instead of using a configuration file created for an Ax client, you are using a configuration file of the Dynamics Ax AOS server.
Make sure to use the Ax client configuration utility to create the AXC file, not the server configuration utility.

Monday, October 10, 2011

What not to forget when using the changecompany keyword

When debugging some Ax code the other day, I stumbled upon some good looking but not working code.  What at first sight looked OK, missed a small but vital detail.

The code involved the use of the changecompany keyword.  It's an easy approach for reading records from different company accounts within one Ax database.
The syntax is pretty straightforward:

   changecompany('id')
   {
       // record handling
   }

Put the record handling between accolades and you are good to go.  But...


Example of some disfunctional code:

static void MyExample(Args _args)
{
   DataArea DataArea;
   CustTable CustTable;
   ;

   while select DataArea
      where !DataArea.isVirtual
   {
      changecompany(DataArea.id)
      {
         while select CustTable
            where CustTable.Name like 'A*'
         {
            info(strfmt("%1 %2 %3",CustTable.dataAreaId,CustTable.AccountNum,CustTable.Name));
         }
      }
   }
} 

The above does not work or gives unreliable results.
What to do: You have to reset your table variable, after the changecompany but before your perform the record handling..
Example of some working code:

static void MyExample(Args _args)
{
   DataArea DataArea;
   CustTable CustTable;
   ;

   while select DataArea
      where !DataArea.isVirtual
   {
      changecompany(DataArea.id)
      {
         CustTable=null;          // remember to reset the record object
         while select CustTable
            where CustTable.Name like 'A*'
         {
            info(strfmt("%1 %2 %3",CustTable.dataAreaId,CustTable.AccountNum,CustTable.Name));
         }
      }
   }
} 

Wednesday, September 28, 2011

Microsoft opening up the vault of KB articles

Up until now, access to Knowledge Base articles for Dynamics Ax was limited to people with access to either CustomerSource or PartnerSource.  This also means access to people with a valid Service Plan for Ax.
Microsoft decided a while ago to align it's policy regarding KB's for Dynamics Ax with other MS products.  This means that all KB articles are now publicly available, no restraints.  Which of course makes it a lot easier to reference them in communication between partners and customers, on internet fora etc.  And it makes them accessible to search engines as well, helping to spread the information.

You can search for any KB over here:

Microsoft Support

or with this more specific link for Ax:

Dynamics Ax Solution Center

30.000+ articles are already available.  And new KB's will be created with a public profile.

Monday, September 19, 2011

Switcher

Microsoft is gaining market share with the Dynamics suite, but only marginally.  Today it still is not a real threat to number one, SAP.  In fact, they are profiling Dynamics Ax as an addendum to SAP, king of the Tier 1 throne.  With Dynamics Ax for subsidaries, branch offices.
 
But with the introduction of Dynamics Ax, they really do target a competitor.  And that competitor is Lawson, with is S3 and M3 software.  Please remember, Lawson is now part of Infor.  Infor has the same ambitious plan as Microsoft had almost 10 years ago: Create one single ERP suite, with one code base.
But as you know, any take-over comes with some uncertainties for both customers and partners.  And Microsoft hopes to benefit from that uncertainty.

Two initiatives under one name are launched: the Switcher campaign.

  • Microsoft is giving up to 50% discounts on the standard list price of Ax 2012, for customers switching from current Lawson ERP software to Dynamics Ax 2012
  • Secondly there is a reimbursement for partners investing in training and certifying their Lawson consultants in Ax 2012
The name of the campaign sounds like a new television series, airing Friday evening.  But it's not, it's real and tempting for people involved with Lawson software today.
And while it will not create a landslide, it will certainly add some percentage points of growth to Microsoft's customerbase and it's partner ecosystem.

Thursday, September 8, 2011

Electronic concrete

Virtual Launch event of Microsoft Dynamics Ax 2012 today.  Can't miss it!  Microsoft really pulled out the big guns.  Steve Ballmer, Kyril Tatarinov, Hal Howard, ...

A one hour event, with a nice mix of promotional talk, some demo's, user experiences.  The message is clear:
  •    Ax 2012 is released
  •    soon on a computer near you
  •    in better shape then ever...
More to come.

Oh and the title of this post?  Microsoft compared deploying it's competitor's ERP as like 'pouring electronic concrete'.  Pretty vivid image, not?

Wednesday, August 3, 2011

Dynamics Ax 2012 is compatible with Windows 7 - Did you expect otherwise?

It looks like a formality, but still they have to go through the proces.  After Dynamics Ax 2009 already got a green light (see here and here), and since Windows XP is no longer supported for Ax 2012 (see here), it was now time to put Dynamics Ax 2012 to the test.

The results of the jury (we didn't expect anything else): Microsoft Dynamics Ax 2012 is compatible with Windows 7.  Now it's official.   (Both 32 bit and 64.)

This means it passed Microsoft installation, performance, reliability, and security tests.
And they can put that on the box :-)

Monday, August 1, 2011

Microsoft Dynamics Ax Technical Conference 2011 in Europe

Good news!  After holding a technical conference earlier this year in Seattle (US) and after announcing a virtual lauch event for Dynamics Ax 2012, it's now time for a Technical Conference here in Europe.  This will take place November 14-16, 2011.
Just to be clear: This is not a virtual event, it's the real deal.  The event will take place in Nice, France.  And that's an extra reason to attend :-)

Who should attend?  Both partners and customers are welcome, functional and technical implementation consultants are expected.
The agenda is not yet published, but you can expect tons of info on the new flagship release of Dynamics.  Like the model-driver layer architecture, integration with Sharepoint and Office (two way), new industry functionality, ... and the list goes on and on.  It will be 3 packed days!

Monday, July 4, 2011

How to retrieve the port number of the AOS within a session

The port number used by an AOS server instance is of course set in the server configuration utility.

But what if you need to retrieve this information from within a session? Or what if you connect to a load balanced cluster and you need to know the currently used port number?
For these kind of questions, the Session class has an answer.  With the method getAOSPort.

See following example:
static void GetAOSPort(Args _args)
{  ;
   info(strfmt("Port number: %1",int2str(Session::getAOSPort())));
}
The Session class has some other nice informational methods, inherited from xSession. Like AOSName (retrieve the name of the AOS server) and clientComputerName (retrieves the network name of the client computer of the session).

Thursday, June 30, 2011

Dynamics Ax 2012 Global Virtual Launch Event set for September 8 2011

Microsoft is increasing his marketing efforts for the next release of Dynamics Ax.  It has scheduled a Dynamics Ax 2012 Global Virtual Launch Event on September 8, 2011.  So watch out for more information to come.

The Ax 2012 info on Microsoft.com, the launch page available to the public, is up for some time already.

PartnerSource, the site for Microsoft Dynamics Ax partners, got updated recently:
See for example the launch page over here or here.

Update: Registration is now open for the launch event, so head over here to register.

Tuesday, June 28, 2011

What can you do if your AOS service is in the stopping state?

For a routine maintenance job you want to bring the AOS server down.  So you stop the service and then... things go terribly wrong.  The Windows service does not stop and remains in the stopping state. 
So now what?  You cannot stop the service, you cannot start it.  Is a server reboot an option?

If there is only one AOS instance installed on your server, it's easy.  By using the taskmanager in Windows, kill process Ax32Serv.exe.

If there are multiple AOS instances on your server, it's a bit more tricky.  All your AOS instances have a process running with the same name, Ax32Serv.exe (Can you afford to kill the wrong process, shutting down the wrong AOS?).


1.  So first you need to identify the correct process.  You can do this by using the sc command.

For this we need to know the precise service name.  We find this piece of information in the Services window, by clicking on the Properties of the AOS service (in stopping state).  Note the name, it will be something like AOS50$nn (for Dynamics Ax 2009).



2.  With this info, query the current running services.  You can use the service controller utility sc for this.
Syntax:

   sc queryex aos50$nn   (use the service name from the previous step)



This gives you the exact PID or process id.

3.  Now we are ready to kill the task:

   TASKKILL /PID nnn /F   (where nnn is the process id from the previous step)

Refresh your screen with the Windows services, and you'll see that the AOS service is no longer in the stopped state.

Please: Use the instructions above at your own risk!
If this happens pretty frequent, look for the error cause instead of just applying this workaround. 
Do you know a better remedy?  Post it in the comments!

Thursday, June 23, 2011

Prediction: Version market share of Dynamics Ax 2012 will not reach 40% before 2013.

Yes it is true: I've used my crystal ball and took a look at the future. Even though it was a bit cloudy (more clouds packing together year after year), it was pretty clear to see.
So here's my prediction: Ax version market share for Dynamics Ax 2012 will not reach 40% before January 1st 2013.

Why do I say that?  Beacuse it makes senses.

I've done two small surveys in the recent past (thank you blog readers, for giving feedback!).  In one of them I asked quit a straightforward questionWill you be upgrading to Ax 2012 the moment it is released?

The results:



Now have a look at a small survey I did a while back around current market share for Ax versions.  It showed that 35% did not yet upgrade to Ax 2009.  If we take into account that of the 65% using Ax 2009 there are a lot of new customers, it means that around half or more of "old" Ax customers never did perform the upgrade.

Sure, the new version has lots of new features.  A lot of improvements.  And comes with new tools to upgrade.
But let's face it: The product also just got a bit more complex.  Again. 

Upgrading to Ax 2012 is not something you do overnight.  It's gonna be a project on its own.  Requiring resources from both IT and the business.  It's gonna take time.  And time is money.  Ax customers willing to upgrade gonna have to convince higher management it's a good investment.  Put it down in black and white.

Some topics to consider:  (but there are many!)

Reporting
You can still use your old Morphx reports (Ax 2012 still supports it), but SSRS is the way to go.  You could ignore Reporting Services with Ax 2009, but that's no longer the case with Ax 2012.  So if you are not already an SSRS master, it's time to upgrade your skills.

Security
We have to go back a couple of major versions in order to see such big changes as to what security concerns.
And it looks like this is still not the final setup, as in the next version after Ax 2012 RLS will no longer be supported (confirmation Microsoft?).

Wednesday, June 22, 2011

How to retrieve the name of your current Ax client configuration

When setting up a Dynamics Ax client, each setup (or configuration) is given a unique name.  You can retrieve this name when working in Dynamics Ax by using the xInfo class.

Example:

static void AxClientConfigName(Args _args)
{   ;
   info(xInfo::configuration());
}

This job shows the name that is selected in the Configuration box in the Client Configuration Utility.

Monday, June 20, 2011

How to update multiple records in one go - the Fill utility in Dynamics Ax explained

The Fill utility in Dynamics Ax is in my opinion one of the most undervalued features.  Maybe it's because this utility isn't that well known, so I decided to dedicate a blog post to it.

First of all: What is it?
The Fill utility allows a user to update multiple records in one go, setting a specific field with a certain value.  Without the help of a developer, without a lot of manual labour (ctrl+c - next - ctrl+v - next - ctrl+v ...).
Examples: Change the item group for a set of items.  Change the credit limit for a group of customers.

How does it work?
1. Open the form that contains the records you want to update.
2. Select the field you want to change and right-click it.  Select the Record info form in the popup menu.



3.  From the Record info form, select the button that reads 'Fill utility'.
4.  You'll get a query form, asking you for the records that needs updating.



Be carefull to set the right criteria in this stage!
5.  Next Ax show you the records that will be updated, according to the criteria you set earlier.  So again, review with care.
6.  In the last step you set the new value of the field you wanted to change (where it all started.)  Press OK and the change will be performed.  (Believe me, it's easier as it seems from the explanation above.)

Some notes:
Is the Fill utility not available?  You cannot find it?
This feature is controlled by a configuration key.  So make sure the administrator enables the configuration key, under Administration - Setup - System - Configuration.  The configuration key for the Fill utility is right under the first header, Administration.

There is also security key involved.  So if a users complains he/she doesn't see the Fill utility button in the record info screen, make sure this user is member of a group with the appropriate user rights.

What have you done?!
If you were a bit too quick pressing next/ok, you can always see afterwards what was changed.  Dynamics Ax keeps a log of updates performed by the Fill utility.  You can find this log under Basic - Inquiries - Fill utility Log.


Which fields are avaible for using the Fill utility?
Or maybe, which are not available.  Not available for use by the fill utility are the fields recid and dataareaid.  Also if the field you select is the primary key of the table (like the itemid in InventTable, accountnum in CustTable), you cannot use the Fill utility.
If the field you select is not a field of the underlying table but a datamethod instead, again you cannot use the fill utility.

Thursday, June 16, 2011

What are the tables InventSumDateTable and InventSumDateTrans used for?

When browsing the AOT, you may come across these two tables: InventSumDateTable and InventSumDateTrans.

Using your table browser, you see that they are empty.  So what are they used for?

Both tables are used by the report Physical inventory by inventory dimension, which can be found under Inventory Management - Reports - Status - Physical inventory
This report takes you back in time, calculating the stock on hand of your items for any given date in the past. 
You might experience some performance isssues when running this report, as some calculations are needed.

The report uses both tables mentioned earlier, to store these calculations.  After generating the report, a cleanup is performed.  So if you should stumble on some left over data in these tables (the user wasn't patient enough and aborted), you can safely delete any data left in these tables.

Tuesday, June 14, 2011

What happens if you go beyond the license expiry date in Ax?

If you have an expiry date on your license of Ax or if you are using a demo license key of Ax, at some point in time the license will become invalid.
What happens is that Dynamics Ax will start to run in demonstration mode. 
Yes, you can keep using the system.  The AOS will not stop.  But....   you are faced with some limitations in the system.

  • The AOT is no longer available for editing, so no more custom coding.
  • There is a maximum of 2 concurrent users.  If more users try to log on, you can get following error message:

  • You cannot enter a date in a datefield on a form, that is beyond the license expiry date.
So all in all you can use Dynamics Ax as your online archive, but no longer for your daily operations.

Sunday, June 12, 2011

How to copy a company account in Ax

When you are using Dynamics Ax, you probably have more than one instance running besides your Live Production system.  Maybe you have some development environments, or test environments.  But even then it can be useful to have a copy of a company, within your Live Production environment.  You can use it for testing purposes or for starting up a new company, with similar settings as the current one.
Microsoft made it actually quite easy to duplicate a company account within Ax, it's almost by clicking a single button.

Step-by-step guide:

Go to Administration - Common forms - Company accounts.




Select the company account you want to use as template, your source to copy from.  Then click Duplicate.
Wait a sec, Ax is investigating the company account.


Next, enter a new company account id, followed by a company name.  (Ax will create this new company account for you, you don't have to manual create one.)
Click OK and you're off.  Depending on the size of your source company account, this can take some time (think of hours).  Not only your master data is duplicated (customers, items), but also all the transactions from the source company account (like inventory transactions, ledger transactions).
You might wanna perform this duplicating outside of office hours and using a batch server for this is also a good idea.

Also note:
The guide above works for Ax 2009, but it won't work in Ax 2012.  In Ax 2012, this function is no longer available, it got deprecated.  Reason, from the official MS documentation: The organization model represents a paradigm shift in Microsoft Dynamics Ax 2012.
In short: You must rely on import and export again in the future.

Wednesday, April 13, 2011

What is the release data of Dynamics Ax 2012?

With Convergence 2011 taking place in Atlanta (US) right now, we see a peak in all the buzz on the web about MS Dynamics Ax 2012, the next major release of Ax.  Microsoft is releasing bits and pieces of information regarding new functionality, technical enhancements and so on.  And they have communicated on the release date as well, giving a new estimate.  As it was previously stated that general availability would be "Q3 2011", everyone expected this to be "September 2011".  But positive surprise:

   MS Dynamics Ax 2012 will be available in August 2011.

(Features and date come with a MS disclaimer, so all tentative right now.)

Tuesday, April 5, 2011

How to format your number the CLR style

Converting (real) numbers to a string representation is a common requirement. There are different roads that lead to Rome, I'll show you some alternatives, which all have one thing in common: They all use Format.

You can use num2str to convert your real numbers to a string, or you can use Format.
Example, controlling the number of decimals showed:  (decimal point acts as decimal separator)

static void FormatExamples(Args _args)
{
    real        mynumber=123.4;
    String30    mynumberstr = System.String::Format("{0,0:#.00}", mynumber);
    ;
    info(strfmt("Your number is %1", mynumberstr));
}

You can use the Format command to add leading zeros also.
Example:

static void FormatExamples(Args _args)
{
    real        mynumber=123;
    String30    mynumberstr = System.String::Format("{0,0:00000}", mynumber);
    ;
    info(strfmt("Your number is %1", mynumberstr));
}

Notice that you can also use rounding like this as well.  Besides this basic function, we can actually do some conversions.
You can use Format to convert to hexadecimal for example.
Example:

static void FormatExamples(Args _args)
{
    int        mynumber=255;
    String30   mynumberstr = System.String::Format("{0,0:X}", mynumber);
    ;
    info(strfmt("Your number in Hex: %1", mynumberstr));
}

Monday, April 4, 2011

A hidden feature of the output window

If you are an Ax developer then you've probably used the Print command in Dynamics Ax, either to do some debugging or during testing of code.  The print command allows you to print some results or some values to screen.  Optionally enter a pause statement at the end, in order to be able to read the actual output.

Example:

static void WindowDemo(Args _args)
{
    print('Hello world');
    pause;
}

Sort of a hidden feature in Ax, is that you can actually control the output window, both size and position.  You can use the Window command for that.

Example:

static void WindowDemo(Args _args)
{
    window 120,60 at 5,5;
    print('Hello world');
    pause;
}
With the Window command in following format

   window deltax, deltay at x,y

x   Top left position of the window, x-coördinate (Horizontal)
y   Top left position of the window, y-coördinate (Vertical)
deltax   Width of the window, in characters
deltay   Height of the window, in lines of text

Monday, March 28, 2011

What is the location of the help files of Dynamics Ax?

Help information of Dynamics Ax is stored in chm files, a common file format used for help files by Microsoft.  CHM or Compiled HTML Help is a proprietary format from MS.  MS provides free tools (like HTML Help WorkShop and Documentation) to create and edit help files.

By default the help files of Ax are located in a sub folder on the client, like for example C:\Program Files\Microsoft Dynamics AX\50\Client\Bin\Help\%LANG%.  You'll notice a subfolder structure following the used languages (that's where %LANG% stands for), like en-us, de, ...

Keeping the help files on the client assures of course fast access to them, low network traffic.  (And probably no security issue.)

As it is possible to create your own help files, or update the existing help files, it can get difficult to update all the local copies on the clients.  So it's very convenient you can also use a central file share to store these help files.

You can set an alternative location for the help files by using the Ax configuration utility and a text editor, like NotePad.
First create your own custom Ax configuration file (axc file) by using the Ax configuration utility.  Then open this newly created axc file as text file with something like NotePad or WordPad and add a reference in following format:

helpDir,Text,filelocation

Example:

sqlpwd,Text,
sqltrace,Text,0
sqluser,Text,
user,Text,
helpdir,Text,E:\YourHelpFolder\Help
warnings,Text,
tracemaxfilesize,Text,10000
tracebuffersize,Text,1024
tracemaxbuffers,Text,120

I recommend using a common fileshare, as this allows for central deployment and maintenance of the helpfiles.  Easier to include in backups, especially usefull if heavy maintenance is done on those help files. You could use a fileshare on the AOS for example.
Make sure the axc file is used by the users for starting up Dynamics Ax.  (The axc file is best placed on a common fileshare as well.)

If a reference is made to a help file that cannot be found, you get an error when the help is called in Ax.


Error: HTML Help file not found.

So, how do we go about to solve the problem above?

Step 1: Which help file is needed?  Which help file is Ax referencing and where does Ax expect the file to be?

The help in the Ax client is shown by using the class SysHelp.  You can for example put a breakpoint in method getChmPath of this class to retrieve the help file name and it's expected location.

Step 2: Make sure access from the client to the help file location is secured.

Does the help file exist?  Is it located in the expected folder?  No special security settings in place that prevent the client to read from the location?
If the help files are missing, it can be an option to copy the help file from a different client.  Or restore it from a backup if it has been accidently removed.

Monday, March 21, 2011

What about the error 'The corresponding AOS validation failed'

When working in Dynamics Ax, you may come across following error:

   The corresponding AOS validation failed.

The error message is usually accompanied by a reference to some table.  You may get the error message on different occasions in Ax (when opening a form or performing an action), working with for example AIF or batch jobs. 

You may think this is security related.  You are correct.  But that doesn't mean you forgot to give some user group the right permissions for some tables.
Making the user member of a group which has full access to the table referenced doesn't make the error go away.
Maybe when you make the user who gets the error message member of the Admin group, the error stays away.  But of course, making every user member of the Admin group is a bad idea and not the way to solve your problem.  So what now?

First, let's trace the error back to its root.

The error message originates from a table method.  Each table in Dynamics Ax has 4 methods for AOS validation available:
  • aosValidateDelete
  • aosValidateInsert
  • aosValidateRead
  • aosValidateUpdate
They are inherited from xRecord and you'll see that most of the time, these methods are not overridden.

For example, table CustTable has no specific AOS validation in place when reading, updating, deleting or inserting records (Customers).  But tables like AifDocumentLog, AifGatewayQueue, BatchHistory do.
Standard Ax 2009 comes with more then 60 of these kind of validations on tables.

Now what are these methods about?

MethodDescription
aosValidateDeleteValidates on the server that the specified record may be deleted from a table.
aosValidateInsertValidates on the server that the specified record may be inserted into a table.
aosValidateReadValidates on the server that the specified record may be read.
aosValidateUpdateValidates on the server that the specified record may be updated.

So these methods give the developer extra tools to limit access to a table.  For example decide who can read from a table, who is allowed to update records etc.  So we have separate security settings in place, besides user group permissions and RLS record level security.
Actually, most of the time it is used to administer some kind of record level security.  A user has access to a table action only when being member of a group, or when the user created the record, or the user submitted something or ...

So what is the solution for your error?  A quick summary:
  • Open the AOT and find the table that is referenced in your error message.
  • Go to the right validation method (are you reading records, updating them, ...)  If you got the error message when opening a form, it is probably the aosValidateRead method which you are after.
  • Check out the actual code to see which users are granted permissions.  Check out the conditions and act accordingly, if possible.
    Maybe setup a separate group ('AIF' or 'Batch'), make the user a member and give access through code (if (AifUtil::isGroupMember(curuserid(), 'AIF')) return true;
Tip
You might wanna read more about a similar error message on this blog.  It talks about AOS authorization.

Friday, March 18, 2011

How to calculate date displacements, working with days, months and years.

When working with date displacements in Dynamics Ax, you can use simple mathematics.
For example, go 3 days back can be written out like:

newDate = today() - 3;

It cannot get any easier.
But this is for days.  May be we want to go back in time or into the future, working with full months or years.  And then the number of days in a month comes into picture.  Mmmm

We can use the DateTimeUtil class from Dynamics Ax to achieve this.  Like we saw in the previous post, this class offers all sorts of calculations for the date.  Use AddDays, AddMonths, AddYears to calculate the date after the offset, working with specific period units.  Use negative arguments to go back in time.
Example:

DateTimeUtil::addMonths(TransDateTime,3);

I've included a short job, that is sort of an extension to the DateTimeUtil class.
It can calculate date displacements for 3 different period units.

The code:

static void DateDiffA(Args _args)
{
   date TransDate;

   TransDate Calcdate(date       startDate,
                      Periods    periodQty,
                      PeriodUnit periodUnit)
   {
      TransDateTime TransDateTime=DateTimeUtil::newDateTime(startDate,0);

      switch (periodUnit)
      {
         case PeriodUnit::Day:
            return any2date(DateTimeUtil::addDays(TransDateTime,periodQty));

         case PeriodUnit::Month:
            return any2date(DateTimeUtil::addMonths(TransDateTime,periodQty));

         case PeriodUnit::Year:
            return any2date(DateTimeUtil::addYears(TransDateTime,periodQty));
      }

      throw error(Error::wrongUseOfFunction(funcname()));
   }
   ;

   TransDate=CalcDate(today(),3,PeriodUnit::Month);

   info(strfmt('The calculated date is %1',date2str(TransDate,123,2,2,2,2,4)));
} 

You can use this code as inspiration to create a new method for the Global class, so you can use it all over in Dynamics Ax.

Thursday, March 17, 2011

How to split a time in hours, minutes and seconds

Just like we can split a date into the year, month and day part, we can do something similar for a time.  We can split the time into hours, minutes and seconds.  And the nice part: we can use the same tool for this as we use for splitting a date.  We can use the DateTimeUtil class.

Here's a short example:

static void GetMyTimeSplit(Args _args)
{   
    TransDateTime   myDateTime=DateTimeUtil::applyTimeZoneOffset(DateTimeUtil::getSystemDateTime(),Timezone::GMTPLUS0100BRUSSELS_COPENHAGEN_MADRID);
    int             hours;
    int             minutes;
    int             seconds;
    ;
    info(datetime2str(myDateTime));
    
    hours=DateTimeUtil::hour(myDateTime);
    minutes=DateTimeUtil::minute(myDateTime);
    seconds=DateTimeUtil::second(myDateTime);
    info(strfmt('Hours %1 - Minutes %2 - Seconds %3',int2str(hours),int2str(minutes),int2str(seconds)));
}

The DateTimeUtil class is like a kind of Swiss army knife when it comes to date and time handling.
As you see from the example above, we use it to populate our TransDateTime variable with the current date and time also.


Tuesday, March 15, 2011

Any2str and the error message 'Internal error 25 in script'

The any2str function is a classic in Dynamics Ax.  It supports conversion from all sorts of data types into a string.  But as you might expect (and as is documented in the help files), only useful output is acquired when working with data types date, int and enum.

But the function cannot do magic.  Unfortunately.
If you take a look at the previous blog post, you might consider the any2str function a help in marshalling need.  (When doing a conversion between CLR primitives and X++ counterparts.)

Take a look at an example that I've copied from that earlier post:

static void DemoA(Args _args)
{
    ;
    info(strfmt('The current folder is %1',any2str(System.IO.Directory::GetCurrentDirectory())));
}

The code above will lead to the following error message:

Error executing code: Wrong type of argument for conversion function.

It gets followed by a more mysterious error message:

Internal error number 25 in script.

So this use of any2str is a definitely no go.

Here is an example: of a workaround:

static void DemoC(Args _args)
{
    str     myFolder=System.IO.Directory::GetCurrentDirectory();
    ;
    info(strfmt('The current folder is %1',myFolder));
}

So lesson learned: When using any2str, stick to the X++ data types as parameters.

If you don't like the workaround above, there is also a nice function in the CLRInterop class that will do the trick, namely getAnyTypeForObject. This function will convert the CLR object to an X++ anytype data type.

static void DemoC(Args _args)
{
    ;
    info(strfmt('The current folder is %1',ClrInterop::getAnyTypeForObject(System.IO.Directory::GetCurrentDirectory())));
}

This code example seems more correct.

Monday, March 14, 2011

How to solve 'Error: Wrong argument type for function' error message when working with CLR

When working with the common language runtime (CLR) and its primitive data types you may run into following error code:

   Error executing code.  Wrong argument type for function.

When you just rewrite your code a bit, all of sudden it works.  Only, do you know what made it work?  Did you find an explanation for the error message?

I try to give some insight on the error cause.  But to give some sort of explanation, we need to look at some theory first.  About X++ and its support for marshalling.
First, let’s look at the CLR primitive types and their matching types within X++.



When working with these types in X++, you’ll see that the X++ does an implicit conversion (also called marshalling) between the two types. This makes it quite easy to mix them in your code. All that is needed is the single equal sign as your assignment operator (=).

Take a look at following example:

static void Marshalling01(Args _args)
{
    System.String   myCLRString;
    Str             myXppString;
    ;

    myCLRString="Hello";
    myXPPString=myCLRString;

    info(myXppString);
}

This will work both ways, so going back and forth between X++ and CLR.

But there is a little catch, when such code doesn’t work.

When you supply the CLR type as a parameter of a X++ method, this might fail. So you must make sure your conversion has been taken place before that.

Rules that apply:
  • An X++ type can be used as a parameter in a call to a .NET Framework method.
  • An X++ type can also be used as a parameter in a call to a X++ method, expecting a CLR primitive.
  • But a CLR primitive cannot be used in a X++ method expecting an X++ type.
So this substitution works one way only.

Example, what will not work:
(but does compile)

static void DemoA(Args _args)
{
    ;
    info(strfmt('The current folder is %1',System.IO.Directory::GetCurrentDirectory()));
}


Instead, what will work.

static void DemoB(Args _args)
{
    str   myfolder=System.IO.Directory::GetCurrentDirectory();
    ;
    info(strfmt('The current folder is %1',myfolder));
}

So make sure you declare a local variable, which you use to do the implicit conversion between X++ and CLR.  And you are good to go.

An extra note on the side:
The only operator to use when working with CLR primitive types is the equal sign =, so by making an assignment. You cannot use other operators, like for example for comparison. So no == or > (bigger than) or < (smaller than).

Friday, March 11, 2011

How to read from the Windows event log from Dynamics Ax

The Windows event log is a valuable source of information, for both hardware and software events.
And the good news is, you can read and write from within Dynamics Ax.  So if you want, you can even write your own events in the Application event log.  Or maybe you want to build some monitoring tool with Dynamics Ax, so you need to read the Security event log from a certain computer.

Here is an example of reading in the Application event log.

static void myEventLogReader(Args _args)
{   
    System.Diagnostics.EventLog                     myEventLog;
    System.Diagnostics.EventLogEntryCollection      myEventLogEntryCollection;
    System.Diagnostics.EventLogEntry                myEventLogEntry;
    System.Diagnostics.EventLogEntryType            myEventLogEntryType=ClrInterop::parseClrEnum('System.Diagnostics.EventLogEntryType','Error');
    str                                             logName='Application';
    str                                             machineName=".";
    int                                             logentries;
    int                                             counter;
    System.DateTime                                 genDateTime;
    TransDateTime                                   mygenDateTime;
    str                                             logmessage;
    ;
    myEventLog = new System.Diagnostics.EventLog(logName,machineName);
    myEventLogEntryCollection=myEventlog.get_Entries();
    
    logentries=myEventLogEntryCollection.get_Count();
    for(counter=logentries-1;counter>0;counter--)
    {
        myEventLogEntry = myEventLogEntryCollection.get_Item(counter);
        
        if(myEventLogEntry.get_EntryType()==myEventLogEntryType)
        {
            genDateTime=myEventLogEntry.get_TimeGenerated();
            mygenDateTime=genDateTime;
            logmessage=myEventLogEntry.get_Message();

            error(strfmt('%1 %2',dateTimeUtil::toStr(mygenDateTime)+' '+logmessage));
        }
    }
}
In the example above we use EventLog, EventLogEntry and EventLogEntryCollection, all from the System.Diagnostics namespace.
Only events of type Error are shown.  To perform the check, we use some form of enumeration.  I've blogged about this in the past, read more about it here.

The example above can be customized.  You can specify another computer, by changing the machineName variable.  Default here is ".", which is the local computer.  (If no machine name is specified, the local computer is assumed.)
Also possible to change is which log is read.  This defaults to the Application log, but you can change this by specifying your own logname.

Monday, March 7, 2011

What's up with that 'Error executing code - AsciiIO object not initialized'?

Picture this:
You are working on a piece of X++ code, where creating a text file is involved.  Maybe you use the AsciiIO class, or maybe you use the TextIO class, the newer installment.  Maybe CommaIO/CommaTextIO is the class you use for creating comma-separated files with Ax.
Your code looks fine (of course it does :-) ).  But still you get this nasty error. 
You have set your permissions, you have initialized the file, set it ready for writing etc.  But still you keep getting this error, even though the code worked fine with other projects.

Error executing code - AsciiIO object not initialized

Tip: You might wanna take a look at the layer the code is executed, server or client.
The code might need to run on the client tier, as otherwise you will get the error message above.  So check you keywords in the declaration, the RunOn-property of the menu-item.
File handling on the server requires some precautions, take a look at the WinAPIServer class.

A short example on how to create a text file with Ax:

static void TextFileDemo(Args _args)
{   
    AsciiIO             tmpfile;
    Filename            tmpfilename;
    FileIOPermission    permission;
    #File
    ;
    tmpfilename = WinApi::getTempFilename(WinAPI::getTempPath(),'DEMO');

    permission = new FileIOPermission(tmpfilename,#IO_write);
    permission.assert();

    tmpfile = new AsciiIO(tmpfilename, #IO_write);

    if(tmpfile.status()==IO_Status::Ok)
    {
        tmpfile.outRecordDelimiter('\n');
        tmpfile.outFieldDelimiter(';');
    } else
    {
        return;
    }

    tmpfile.writeExp(['column1','column2','column3']);
    tmpfile = null;
    CodeAccessPermission::revertAssert();
}

Wednesday, March 2, 2011

What is happening with Axapta?

Take a look at the following graph:




Now I ask you, what’s happening with Axapta?

Axapta was the name used when Damgaard, a Danish company, released it’s brand new ERP solution on the end of the nineties. Later on Damgaard merged with Navision, before it got acquired by Microsoft in 2002. In an effort to align its business software, Microsoft rebranded its ERP portfolio. Axapta was renamed to Dynamics Ax.

But even though the name now is officially Dynamics Ax, the name Axapta is still widely used.

The graph above is from Google Insights, a Google site that gives you – well – insights in search data. For example trends in searches on the web, geographical differences etc.

From the graph above we see that the name ‘Axapta’, even years after it has been replaced as the name for the ERP software, is not dead yet, but still actively used by people all over the world. Usage slowly fading.

And what about the name Dynamics Ax you may say. It already seemed to have reach its peak, but holding position now.


A hint for the marketing guys over at Microsoft?

Tuesday, March 1, 2011

How to get a list of all tables within the AOT

Our challenge for today: Get a complete list of all tables within the AOT.

We could try to use table UtilElements for that, but please bear in mind that you would get multiple listings for the same table if it exists in different layers.

We gonna use a slightly different approach, by using the Dictionary class of Dynamics Ax.  This class provides us with the necessary information from the AOT.

static void TableList(Args _args)
{
    tableId         tableId;
    int             tablecounter;
    Dictionary      dict = new Dictionary();

    for (tablecounter=1; tablecounter<=dict.tableCnt(); tablecounter++)
    {
        tableId = dict.tableCnt2Id(tablecounter);
        info(dict.tableName(tableId));
    }
}

Monday, February 28, 2011

Another way of reading in Active Directory from within Dynamics Ax

Some posts ago we talked about reading in the Active Directory from Ax.  We used some CLR for that.  But as it is so many times with Ax, Ax has it's own routines readily available to do the job as well.  Let's look at the class xAxaptaUserManager and xAxaptaUserDetails.

Some examples:

How to get the SID from AD for a domain user:

static void GetSID(Args _args)
{ 
   xAxaptaUserManager xUsrMgr = new xAxaptaUserManager();
   ;
   info(xUsrMgr.getUserSid('youruserid','youraddomain'));
}

Note: Remember you can user the field networkalias from table UserInfo to do a conversion from Ax user id to the domain user id.

You can use this class for various purposes. Also for checking a password.

How to validate the system password in AD from within Ax

static void CheckPassword(Args _args)
{   
    xAxaptaUserManager  xUsrMgr = new xAxaptaUserManager();
    ;
    if(xUsrMgr.validatePassword('youruserid','youraddomain','yourpassword'))
        info('Password correct');
    else
        error('Password incorrect');
}

We could get some more information from the AD regarding the user by using class xAxaptaUserDetails.

How to get the user name from AD for a user

static void GetADUserName(Args _args)
{   
    xAxaptaUserManager  xUsrMgr = new xAxaptaUserManager();
    xAxaptaUserDetails  xUsrDet;
    ;
    xUsrDet = xUsrMgr.getDomainUser('youraddomain','youruserid');
    
    if(xUsrDet)
        info(xUsrDet.getUserName(0));
}

How to get the email address from AD for a user

static void GetADEmailAddress(Args _args)
{   
    xAxaptaUserManager  xUsrMgr = new xAxaptaUserManager();
    xAxaptaUserDetails  xUsrDet;
    ;
    xUsrDet = xUsrMgr.getDomainUser('youraddomain','youruserid');
    
    if(xUsrDet)
        info(xUsrDet.getUserMail(0));
}

So the AD holds no secrets for one that knows Ax...

Friday, February 25, 2011

How to get the first and the last day of a month

When working with dates for a range in a SQL select statement, you may be in need for the first and the last day of a certain month.  What at first seems a bit difficult to calculate (not all the months have the same number of days for example), is pretty easy to accomplish with the right tools.

 
The first day of a month

 
You can fool around with things like mkdate, so something like this:

 
static void FirstOfMonth(Args _args)
{ 
   TransDate TransDate=today();
   TransDate FirstOfMth;
   ;

   FirstOfMth=mkdate(1,mthofyr(TransDate),year(TransDate));

   info(date2str(FirstOfMth,123,2,2,2,2,4));
} 
 
But there is a readily available function in the Global class, albeit somewhat hidden: DateStartMth.
 
So your code could read like this:
 
static void FirstOfMonth(Args _args) 
{
   TransDate TransDate=today();
   TransDate FirstOfMth;
   ;
   FirstOfMth=DateStartMth(TransDate);

   info(date2str(FirstOfMth,123,2,2,2,2,4));
} 

 
The last day of a month

 
Just like with the first day of a month, we have a function that will do the job for us: endmth
This function calculates the last date in the month of the date specified.

static void LastOfMonth(Args _args)
{
   TransDate TransDate=today();
   TransDate LastOfMth;
   ;

   LastOfMth=endmth(TransDate);

   info(date2str(LastOfMth,123,2,2,2,2,4));
}
 
You may want to check out following functions as well, with some other date functionality: