Wednesday, 3 November 2010
Dynamics AX Easter Egg
I know it's a "bit" off-season, but funny nonetheless
static void easterEgg(Args _args)
{;
info(conPeek(new HeapCheck().createAContainer(), 4));
}
Sunday, 20 December 2009
MSDN with wiki content on AX 2009
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
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
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.
Tuesday, 17 February 2009
How to tell if a form was opened with '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();
}
Monday, 20 October 2008
RunBase - classes and Best Practice
There are certain classes which serve as excellent templates. One such class the LedgerExchAdj-class. If only all runbase-classes were as this one. In my opinion its simplicity and readability is top-notch. I've edited the class-specific code so that only the run() template is present, which included that all important error handling, which one might forget
public void run()
{
#OCCRetryCount
;
try
{
ttsbegin;
// Insert code here
ttscommit;
}
catch (Exception::Deadlock)
{
retry;
}
catch (Exception::UpdateConflict)
{
if (appl.ttsLevel() == 0)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::UpdateConflictNotRecovered;
}
else
{
retry;
}
}
else
{
throw Exception::UpdateConflict;
}
}
}
Friday, 3 October 2008
Setting Cross-reference update in a Schedueld task
An updated Cross reference is an indispensable tool when developing for AX but the client-side dependency can be annoying. So after a little research I found the command line parameter/Windows build-in Scheduled task combo and it does the trick.
In the class SysStartupCmd's construct the command line parameter compileAll-startup command the the parm _+ instantiates a complete compile and cross reference update which means that if you set-up a Scheduled task in Window's standart scheduled task tool with the parameter -startupcmd=compileAll_+ you can update when it suits your development team best.
Tuesday, 26 August 2008
MB6503 - AX 4.0 Installation and Configuration certification
Wednesday, 20 August 2008
OpenOffice and Dynamics ax
static void Job2(Args _args)
{ COM OpenOffice;
COM DeskTop;
COM Document;
COMVariant arg;
Array arr = new Array(Types::String);
//Creating instance of OpenOffice.org
OpenOffice = new Com("com.sun.star.ServiceManager");
DeskTop = OpenOffice.CreateInstance("com.sun.star.frame.Desktop");
// create and initialize a COMVariant object
arg = COMVariant::createFromArray(arr);
//Creating the document
Document = DeskTop.LoadComponentFromURL("private:factory/scalc", "_blank", 0, arg);
}
Original post by Ivan Kasperuk
Monday, 7 July 2008
How to close a form after a certain timespan
On the forms run:
public void run()
{
str JmgJobId;
// Define variable for timeout
// Created with new int on JmgParameters
int TimeOut = JmgParameters::find().JmgRegistredOnJobPromptTime;
// Check if there is a parm
if(element.args().parm())
{
JmgJobId = element.args().parm();
jobIdTxt.text(JmgJobId);
}
super();
// Close form after TimeOut
this.setTimeOut(identifierstr(close),TimeOut);
}
Monday, 28 April 2008
Inside Microsoft Dynamics AX 4.0 free e-book
Friday, 18 April 2008
Applying agile software development to Dynamics AX development part I
The courses I followed at university were mainly concered with the whole development process(es) from early conceptualization to post-installation maintenance, including GUI-development and Business Intelligence reports. Therefore when I started developing (or should I say customizing -a point to which I will return later) Dynamics AX for customers, my craze - User-Centered Design - slowly fell to the background. Is customizing an ERP-programme, such as Dynamics AX, merely a question of replicating exsisting business processes, with some optimization, and merging them into a new ERP-application or is the development of an ERP-solution an almost god given chance to take a critical bird's eye view of the whole organization and try to optimize business processes all the way r0und? The latter would seem the obvious answer but this again begs another question, viz.: can business processes be optimized isolated from the software development process, when the software has a central place in today's organizations? No. Of course it cannot.
All to rarely is there any substantial software development theory included in the business development plan for the implementation of a ERP-system. Traditional user-experience studies / examinations are left behind, because the UI is developed for us, as part of the standard application in the Dynamics-series, and it is 'just' (I know I'm a bit hard here - but I'm trying to get my point through) a question of rearranging data-presentation, based on the customer's prior ERP-system or an external system. All too often does the customer say something like 'that's not the way it was in the other system' when confronted with an newer version of, lets say Dynamics AX.
So the big question is: how do we - as software developers and business consultants - merge the two worlds and come-up with a process which will lead to sound business optimization and software development integrity?
Tuesday, 8 April 2008
Import items into InventTable and associated tables
static void InventTableImport(Args _args)
{
//
//Author : Steffen Denize
//Purpose : Demonstration for importing InventTable into Dynamics AX
//
InventTable inventTable;
CommaIO inFile;
Filename filename;
Dialog dialog;
DialogField dialogField;
ItemId itemId;
int counter;
InventTableModule inventTableModuleBuf;
InventItemLocation inventItemLocationBuf;
ItemName itemName;
;
//
// Note - In this example, I have used 'Dialog' & DialogField classes
// as a tool for me to select the file that has to be imported.
//
dialog = new Dialog("Demo of import of items into a blank InvenTable");
dialogfield = dialog.addField(typeid(Filenameopen), "File Name");
dialog.run();
if (dialog.run())
{
filename = (dialogfield.value());
}
//
// Note - In this example, I have used CommaIO class. But you can also use
// AsciiIO class as well. Basically all these classes (AsciiIO, CommaIO,
// Comma7Io etc) derives from 'Io' base class. For more info, please
// refer to Io class.
//
inFile = new CommaIO (filename, 'R');
if (!inFile || infile.status() != IO_Status::Ok )
{
//strfmt - function for formatting text string
throw error (strfmt("@SYS19312",filename));
}
ttsbegin;
// Set the delimiters
infile.inFieldDelimiter(';');
infile.inRecordDelimiter('|');
//Checking status of last operation
while (infile.status() == IO_status::Ok)
{
// Setting container according to datatypes
[itemId, itemName] = infile.read();
if (itemId)
{
if(!InventTable::find(itemId).RecId)
{
inventTable.initValue();
inventTable.ItemId = itemId;
inventTable.ItemName = itemName;
// These values must be set on their respective tables.
// Here the value are hard-coded into the import as the import
// serves a demo purpose only
inventTable.ItemGroupId = 'TST';
inventTable.ModelGroupId = 'TST';
inventTable.DimGroupId = 'TST';
inventTable.Insert();
// Values must be setup in inventTableModule, which in Dynamics AX 4.0SP2 has three valid arrayelements
// purch, sales, invent (DEL_smmQuotation is not included in this job)
for(counter = 0; counter <= 2; counter++)
{
inventTableModuleBuf.ItemId = inventTable.ItemId;
inventTableModuleBuf.ModuleType = counter;
inventTableModuleBuf.insert();
}
InventItemLocationBuf.ItemId = inventTable.ItemId;
InventItemLocationBuf.inventDimId = InventDim::inventDimIdBlank();
InventItemLocationBuf.insert();
}
}
}
ttscommit;
}
Please notice that the posting is provided "as is" with no warranties and confers no rights
Friday, 28 March 2008
First impressions of Dynamics AX 2009 CTP
As a system engineer, I naturally looked for new things on the developer side of the upcoming version. On of the things I really missed in 4.0 was a build-in version control option. I know you had the option of installing a VSS-server to take care of Version Control for your installation, but the installation process was cumbersome, in my opinion; especially if you only required version control for a single installaion. In the CTP of Dynamics AX 2009 you have no less than four different option of Version Control at your finger-tips.

This will really ease the use of version control as the development team can chose exactly the type of version control which suit their needs. The MorphX VCS is a local, application integrated version control, which does not require any further software installation, which makes it perfect for smaller development teams, which might not have a use for the Team Foundation Server or a Visual SourceSafe. The MorphX allows the development team to check whole projects or single/multiple items from the AOT and has the option of adding descriptions.
Another nifty feature is the export to Excel-button, which pretty much exports the current records to an Excel-spreadsheet.
This is an easier and faster way to extract simple data, which most likely will come in handy for a large number of users.These are just some of the changes in the upcoming version of Dynamics AX 2009 and my first impressions are that the consolidation of user-interfaces across other MS products will ease the transition from previous version of Dynamics AX to upcoming 2009-ed.
Wednesday, 26 March 2008
Dynamics AX 2009 CTP3 release
It's available for download from PartnerSource (requires a PartnerSource login).
One of the many exciting new features is the Role centers and the new integration with Microsoft Project Server. I'm personally really looking forward to getting my hands on this CTP3 and experiencing many of the new features which this upcoming version has to offer.
You can find a comprehensive description of the features in the Dynamics AX 2009 on PartnerSource from the What's New in Dynamics AX 2009 (requires a PartnerSource login).
Hope you find the CTP3 as exciting as I do.
Tuesday, 16 October 2007
Faster data import in Dynamics AX
Notice that you will lose audittrail of the transactions.
The tip is as follows :
Go into Class SysDataImport, and into the method : updateTransactionId()
Make it return early as possible from this method, and everything goes quick.
Just create it like this :
private void updateTransactionId(TableId _tableId, CreatedTransactionId _oldCreatedTransId, ModifiedTransactionId _oldModifiedTransId)
{
CreatedTransactionId newTransId = 0;
;
// Return as early as possible to increase import speed
return;
if (!hasTransIdSupport)
{
return;
}
if (hasCreatedTransId[tableIds[_tableId]])
{
.
.
.
}
Do likewise with method updateTransactionIdReference().
This posting is provided "AS IS" with no warranties, and confers no rights.