Sunday, 20 December 2009

MSDN with wiki content on AX 2009

There are many reasons why we bloggers blog, depending on the type of posts you post of course. Some rant about their personal relationsships, some about political stuff, and yet some about their work and / or hobbies. I fall into the last category - my posts are for myself ( so I don't forget stuff ) and for other AX people, much in the same way as Willy. When I started on AX development I knew only very little about programming in practice and very much about theory ( having a MA in Information Technology ). During my studies I buddied up with Tino at the VISL-project where I did the user-oriented studies and he did the programming ( his programming skills are still out of this world ).

So when it got round to AX development, I was scared s**tless over the lack of how-to's, documentation and manuals for AX. Much of know-how seemed to be anchored in the people who somehow were in contact with the Damgaard company or former Damgaard employees and the most common respons to programming problems was "see if you can find similar functionality in the std. application, and steal with pride". However, many of the problems were not represented in the std. application though of such a general nature, that someone out there must have a solution or hint to how to solve it. And this is where blogs and forums enter the scene. There are a plethora of blogs and forum posts out there which deal with, suggest solutions to an almost ever increasing pool of good questions ( imo - there are no stupid questions ).
Two of the sites which helped me - and continue to do so - are Axaptapedia and the Axapta Programming site and to a lesser extend MSDN, and this blog is my way of repaying the AX community in the same way I was helped in my hours of need for specific problems, and general discussions on AX related stuff.

Then I read the Microsoft Dynamics AX SDK Updates Blog and as of Nov. 10th Community content ( or wiki content ) can be added to articles ( currently only SDK 2009 - but 4.0 is in the making ). Great days are ahead of us - more books on X++ development are published now than when I started, the most recent ( 'Microsoft Dynamics AX 2009 Programming : Getting started' by Erlen Dalen ) appears to be an up-to-date of Steen Andreasen's MorphX IT ( which I still recommend to new AX developers ), but adding the possibilty of contributing to MSDN will increase it's overall value to AX developers out there. Kudos to the MS AX2009 SDK team which do a great job adding value to the documentation which was sparse to say the least until an increased effort from MS came about some years ago.

Happy hacking,
Steffen

Tuesday, 24 November 2009

Pass by reference vs. pass by value

This one is for myself, as I often forget how to implement pass by reference and pass by value, and what the difference is between them.
Pass by reference:

Declare varible and set it :
SalesLine salesLine = salesLine4

Down-side is if salesLine4 changes - so does salesLine

Pass by value:

SalesLine salesLine;
salesLine.data(salesLine4);

Happy ax-hacking

If salesLine4 changes - salesLine doesn't

Monday, 16 November 2009

Deleting duplicate records in SQL

Recently I needed to delete some duplicate records across several companies in AX. The table is self-contained so I needn't worry about delete actions or validation and as there are several companies I wanted to try and do it SQL-style. So this is what I came up with

DELETE FROM [Table with Duplicates]
WHERE [Primary Key Field] IN
DELETE FROM [Table with Duplicates]
WHERE [Primary Key Field] IN
(
SELECT a.[Primary Key Field]
FROM [Table with Duplicates] a,
[Table with Duplicates] b

WHERE a.[Primary Key Field]!= b.[Primary Key Field] -- i.e. Userkey
AND a.[Value to check]= b.[Value to Check] -- i.e. Lastname
AND a.[Second Value to Check] = b.[Second Value to Check] -- i.e. Firstname
AND a.[Primary Key Field] < b.[Primary Key Field] -- i.e. Userkey
)

Respect to the original poster at SQL Server forum.

Remember always to backup your data and try the SQL-statement on a test table before you do anything on data which will be used in live environments.

Wednesday, 2 September 2009

The future of X++

During the summmer Microsoft announced that X++ based Web User Interface is discontinues in the next version of EP which hardly comes as a surprise - Dilip has some nice thoughs on the subject, and as he says this will allow developers to use Web 3.0 Framework.

On Channel 9 - "Dynamics Program Manager Peter Villadsen and Software Developer Gustavo Plancarte teach us about a new tool they've developed that translates X++ byte code into MSIL. We learn a lot of history along the way and gain insights into the process of taking X++ into the .NET age.

Microsoft Dynamics features a proprietary language called X++ (basically a superset of Java, with some strong data primitives added) and a complete stack (compiler, interpreter and debugger) that goes with it. The new feature Peter and team have developed is a tool to generate managed code from the X++ intermediate language produced by the X++ compiler. This will have profound impact on the performance of the business applications written in X++, and it very clearly points to where they'll be going in the next few releases of Dynamics Ax."

Watch the video here.

My thoughts on the subject - as I posted on Dilip's blog, is that X++ sooner than later will become the new COBOL; 'pure' X++ code and developers will never die completly due to the exsisting code-base already out there, which has to be maintained but when the full implementation of an intermedia langauge parser comes into exsistence .NET programmers will be able to code Dynamics AX customizations in e.g. Visual Studio. There are many blessings in X++ - Extended Data Types and it's function to name one - which does not exsist in other languages ( to my knowledge ) which newer generations of developers will probably not fanthom if the platform will be migrated completly to the .NET-platform.

The progress begs the question - what are the advantages in the migration from X++ to .NET? Hard to tell for a X++ 'evangelist' but one thing could be the that Microsoft wish to consolidate NAV and AX development to the .NET platform through the intermediate language and thus open ERP development to the many exsisting .NET developers. This will perhaps position Microsoft better in the ERP market versus e.g. SAP if in a few years all the .NET programmers will be able to develop ERP solutions?

The days where a X++ developer could get by with "only" SQL and X++ skills are soon to end. Already for ISVs to give customers the full advantage of their Dynamics AX 2009 investment, their competencies has to include .NET programmers and Business Intelligence people (e.g. MDX, Reporting Services) on top of the traditional X++ and SQL teams. This will bring new challenges to ISVs and Dynamics AX team composition.





Saturday, 18 July 2009

Office 2010 Technical Preview


Beta testing - technical preview - the words make me tingle, and getting the opportunity to actually get my hands on alpha/beta/RC software makes me tingle even more. I've done my fair share of pre-rtm testing in my time, e.g. running Firefox before it actually was called Firefox, writing this blog post on my Windows 7 64 bit RC box, loving Opera 10 which had many of the features that IE and Firefox later adopted and doing QA for OpenOffice.

So last week I tingled a lot as I had the opportunity to join the technical preview community of Microsoft Office 2010. I grabbed the chance to install the 64-bit version, which is one of the new features of Office 2010, on my windows 7 box, and installation was a breeze.

Having a 64-bit version of Office 2010, the Office package probably being the defacto stadard of productivity suites, is a clear indication that 64-bit software is the future, and that 64-bit will most likely be gaining ground in production environments: "With Office 2010 64-bit edition, advanced users will be able to leverage the increased memory capabilities of 64-bit computing and harness this capability for analysis and manipulation of very large data sets and documents" though some VBA code require reengineering to work with the 64-bit version ( from the technical preview site ).

So let's get on the with the preview, starting off with Word 2010














One of the things I do at work is writing documentation, both technical and user-oriented. In AX 2009 ( and 4.0 - with the prober add-on ) I have Task Recorder at my disposal for easy and fast creation of user-oriented documentation. However, sometimes I need finer detailed screen shots than Task Recorder can provide so I use SnagIt for my needs. This works fine.

In Office 2010 this features has been combined with Windows 7's Snipping Tool so that you can actually past previously snipped screenshots directly into your word documented, e.g.:












This functionality does not make third-party programmes superfluous, such as SnagIt, which has many more excellent and useful functions; the funcinality in the Snipping Tool is pretty basic, but it demonstrats how Microsoft manage to integrate/couple standard Windows functionality with other products in the software portfolio.

This is just one of the new features of Office 2010 and as I spend some more time using it, I will most likely post some of my findings. If you have any questions regarding features of Office 2010, drop me a comment and I will see if I can find it.


Thursday, 25 June 2009

Copy - paste utility

The lack of IntelliSense in the MorphX IDE ( and being too cheap to invest in AxAssist ) made me browse for an alternative. I found ArsClip which is a nifty little tool for copying and pasting; and not just for programming. It can hold your Copy and with the right setup Ctrl-Shift-V will show you a list of you previous Copy ready to be inserted.

Sunday, 14 June 2009

x++ and C# compared

One indicatation that Dynamics AX developers need to learn C# in order to take full advantage of future versions of AX is when MS starts documenting differences in coding practices.

Personally, X++ was the first programming language which I've felt pretty comfortable with even though I've done som Java programming ( and the mandatory html coding which most programmers start out with ).

I see the need for AX developers to hone ( or just begin on ) their C# skills with the introduction of EP ( version 2009 ) and the reporting service integration with e.g. the role center. I've done som Hello Word-ish programming in C# using Visual Studio 2008 and I must say that I like it. One area where X++ and MorphX out ranks C# and VS is form development. After having created some rather basic forms in C# using VS it was a pleasure returning to MorphX's drag and drop design.

From what I can gather future version of AX will include a brand new approach to the layers and id ranges on elements but these advantages a side - MorphX still could adopt some of the features from VS, in my opinion. One thing I really like about VS is it's IntelliSense (Thanks Morten)"smart typing" ( I don't know what else to call it - but it's the feature when you start typing something VS automatically completes the string ) - it can be done; AxAssist does it for you - but why not integrate the functionality into MorphX as a standard? Well - perhaps in AX 6?

ODBC with FoxPro

I recently had the pleasure of adventuring into the ODBC connection territory. I discovered that many others previously had done the same ( obviously ) but there was a surprising lack of how-to and other documentation. After some extensive searching I found Brandon's blog in which he meticulously documented an implementation of ODBC. Many excellent observations are included in his description, including AOS considerations, i.e. code-execution placing vs. maintenance of Windows ODBC connection ( he runs the code on the AOS server so that the system ODBC connection driver only needs to setup there and not on the client which would reduce maintainability as changes to the connection potentially would have to be distributed to all clients ).

If you are implementing an ODBC connection for the first time on AX 2009, I highly recommend reading Brandon's step-by-step description.

So implementig an ODBC connection should be a run of the mill type of assignment, had it not been for one small detail... FoxPro. One of Brandon's main consideratations was exactly that the ODBC connection should be created on the AOS, but the systems requirements for the AOS in the case in question on which the ODBC connection would be created stated that the OS ( Windows Server 2008 ) should be 64-bit, and FoxPro only runs 32-bit and since the AOS instance in AX2009 runs in 64-bit mode - it cannot access the 32-bit FoxPro drivers ( and as far as I could tell there never will be a 64-bit implementation of the ODBC drivers for FoxPro ).

So maintainability aside - I had to distribute the ODBC connection to all clients force the class which handles the code to run on the client. This can be done since the AX2009 client still runs 32-bit ( and in 32-bit mode on 64-bit OS ).

Task completed - but the journey probably would have been longer and more tedious had it not been for Brandon's blog.

Hope my expericences with FoxPro ODBC connection in connection with AX2009 helps someone, just as Brandon's blog helped me.

Happy hacking

Thursday, 14 May 2009

Import csv job

Here is an import job for importing tuples from a csv file:


static void importJob(Args _args)
{
    FileIOPermission        permission;
    AsciiIo                 file;
    Filename                fileName = @"c:\test\test.csv";
    CustTable               custTable;
    container               line;
    #define.fieldDelimiter(";")
    #define.recordDelimiter("\n")
    #define.read("r")
    ttsBegin;
    permission  = new FileIOPermission(fileName, #read);
    permission.assert();
 
    file = new AsciiIo(fileName, #read);
    file.inFieldDelimiter(#fieldDelimiter);
    file.inRecordDelimiter(#recordDelimiter);
 
    if(!file || file.status() != IO_Status::Ok)
    {
        throw error(strFmt("@SYS76826", file));
    }
 
    while(file.status() == IO_Status::Ok)
    {
        line = file.read();
     
        custTable.AccountNum = conPeek(line, 1);
        custTable.insert();
    }
    ttsCommit;
     


}
Happy hacking

Saturday, 2 May 2009

Opening a form on start up of AX

I've recently implemented a variation of Palle Agermark's post on how to run a form on start up of AX. He opens a form through calling the Display menu item. I needed was to call a form with conditions, so I created a class which would handle the conditions in question and instead of calling the menu item I called the main method of the class




Thanks to GregP for his helpful tips and insisting that he could get it to work.

EDIT: There is a small aber dabei ( which roughly translates "there is a but", I just happen to like the German term better ). In order for the AutoRun to function, development rights for the user-group are necessary, as the function we utilize is typically used to automate installation/configuration. Giving the user group full development rights though is not an option in this scenario, so after some fiddling about I found that the only security setting the user group needs is SysLastMinuteCheck




which, by the way, only can be set giving the user group full development right and then removing all but this SysLastMinuteCheck.

Tuesday, 17 February 2009

How to tell if a form was opened with 'Go to main table' function

I found this sample code really helpful in connection with a customization,where the customer wanted to alter the 'Go to main table' function.

Respect to original poster (though I can't remember where I found it - but the idea is not mine)

On main datasource:
public void executeQuery()
{
query q;
querybuilddatasource qbds;
querybuildrange qbr;
int fldLookupField;
str sLookupValue;
;
if ( element.args().caller() &&
!element.args().dataset() &&
element.args().lookupField() &&
element.args().lookupValue()) //jumpref
{
sLookupValue =element.args().lookupValue();
fldLookupField =element.args().lookupField();

q=this.query();
qbds=q.dataSourceTable(this.table());
qbr=qbds.addRange(fldLookupField);
qbr.value(sLookupValue);
this.query(q);
}
super();
}

Friday, 13 February 2009

Invoking a method on a field in a form's datasource

I needed to call the modified method on a form's datasource's field to invoke the logic, which updated a couple of fields on the form. I had defaulted a value in the field on the table's initValue()-method but this - of course - means that the modified method is not in play.
Therefore I needed to call the method in code, for which I had two options, either calling the form controls method by setting AutoDeclaration to Yes and then calling modified or calling the datasource table's field's method which I chose.

e.g. ProdTable_ds.object(fieldnum(ProdTable, ItemId)).modified();

but where to place the code? After some time I found out that if I placed it on active() of the datasource the form showed the correct information.

/Happy hacking

Monday, 5 January 2009

Show current configuration in title bar of windows

This code snippet shows the current configuration of the AX client you have opened. Really helpful if you have several different AX clients opened at the same time.

void workspaceWindowCreated(int _hWnd)
{
SqlSystem sqlSystem = new SqlSystem();
LoginProperty loginProperty = sqlSystem.createLoginProperty();
;

// Put workspace window specific initialization here.

// Show application details in title bar
if (loginProperty)
{
WinAPI::setWindowText(_hWnd, strFmt("%1 - %2@%3 (%4)", WinAPI::getWindowText(_hWnd), loginProperty.getDatabase(), loginProperty.getServer(), this.currentAOLayer()));
}
}