Tuesday, August 21, 2012

AX 2012 Database Temp Table

From MSDN:

...One type of temporary table is a TempDB table. They are called TempDB tables since the TableType property value is TempDB (TableType::TempDB). The TableType property value can be set from AOT > Data Dictionary > Tables > MyTempDBTable > Properties > TableType.

All types of temporary tables are automatically dropped by the system when the table variable in X++ goes out of scope. A TempDB table is not dropped when you set its record buffer variable to null.

TempDB tables are a different type of temporary table than InMemory tables. For more information, see Temporary InMemory Tables.

For more info:

AX 2012 AIF

Some quotes from technet:

"The AIF framework has been updated to enable developers to expose X++ business logic as WCF services. ASMX Web services have been replaced with WCF services enabling new functionality such as message encryption."

AX2012 Startup options

The startup options are described here:
http://technet.microsoft.com/en-us/library/aa569653.aspx

Example: If you want to make a shortcut that reads a configuration file (AX2012_VAR.axc) and starts the development environment:

D:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin\Ax32.exe -development "D:\Program Files (x86)\Microsoft Dynamics AX\60\config\AX2012_VAR.axc"

Thursday, May 10, 2012

XPO Editor update

Hi,

I've done alot of work lately on this project. Here's a quick update so far:
  • Added application scripting (ECMA standard). Need more of the application available, but works great. Need to make a application startup and close script in case I need it later.
  • Docking windows
  • Added a syntax highlighting code editor
  • Imports most of the Table elements and all Classes.
  • Can edit Table and Class methods
  • Many improvements on the SQL layer
Screenshot:



Wednesday, May 2, 2012

XPO viewer and editor

Earlier I wrote about a XPO viewer which I used for a quick view of the content in a XPO file.

Often I use a lot of time to searching through XPO files to reuse code that is verified/tested - instead of writing the same code again with a probability for errors. The mentioned XPO viewer don't do much beside showing most of the AOT for the file imported. If you have a large XPO file/project and want to reuse it in another Ax environment, the only way so far is to have a clean Dynamics AX installation and import the XPO file and edit the elements there, then export to an new XPO and import it in the customers test-environment. You could import it directly to the test-environment, but then you will have to deal with elements that most likely should not be there, e.g new security keys, labels, fields in standard tables, menu items etc..

So, I have now started on a XPO application for organizing,viewing and editing XPO files. The reason for this application is to have the XPO files organized in a database and a better way to reuse code and projects. It will be easy to import, edit and export XPO projects in addition to search for AOT elements in many XPO files in one search. I have completed about 10% of this application.

If you have any suggestions about functionalities, please add a comment.


Screenshot of the development so far.. need to work with design, icons, and lots of other stuff. Next in my todo list is to add a syntax highlighting editor and a scripting engine. 

BTW: I'm using a multi-platform code library called Qt, so if needed - this application can be easily transferred to Linux, Mac etc.... but I don't see the reason for doing that :-)

Thursday, March 29, 2012

Microsoft Dynamics AX 2012: Programming Model Improvements - Part 1

Here are a some info from a lecture on improvements in Ax2012 programming part 1. You will find the complete and free video (1 hr 15 min) presentation at Microsoft Partner Training web (BTW: You will need an account there):

Course description: The investment in tooling and framework improvements for the developer is vast. In this session see a snapshot of the investments in three key areas: Data access, the X++ language, and in the Services programming model. Data access abstractions like Relationship Modeling, Table Inheritance, Date Effectivity, Unit of Work and improved Caching will be covered. Also covered will be the X++ features of Eventing based customization and strongly typed interop from .NET to X++ that help you develop robust customizations for Microsoft Dynamics AX 2012. Finally we will provide an overview of Servic It's about writing less code and writing better code!es programming model that is geared towards opening up development for Dynamics AX to a whole variety of application platforms, including mobile platforms via standards compliant web services.

Screenshots from the videopresentation (c) 2011 Microsoft

Monday, March 26, 2012

Grid search filter

When you have focus on a form grid, you can press Ctrl-G to get a seach filter
like this one:



If you want to have this as default in a form, you will only need 2 code lines in the run method on that form and switch the autodeclaration on for the grid that need this:


Here is a code example (if there is no run method in your form, just create one):

#SysTaskRecorderMacro
public void run()
{
    super();

    // <- Turn the autofilter on in the grid
    grid.enter();
    this.task(#sysTaskRecorderTaskFilterByGrid); // Macro = 2855
    // Autofilter on ->
}





Wednesday, March 21, 2012

XPO Viewer

Here is a cute little XPO viewer. I have tested it with Ax 2009 and i works. I use it to have a quick look inside XPO's before I import it. You will only see a list of objects not the code.

Screenshot:

Monday, March 5, 2012

Emails

If you need to send emails from Ax 2009, you have several options:

1. Using the Microsoft CDO library for sending email like mentioned on this blogg.
2. The Ax SysMailer class (MSDN).
3. For Lotus Notes integration there is several 3rd party kits, like this one called Intograte (I have used this one several times).
4. Flat file: Most email services accept ASCII files as input that is formated according to the MIME standard. You just build the text string and write it to the file.

Please comment if you have other ways to generate/send emails....

Thursday, March 1, 2012

Query information in a report header

Today I had a case where I needed the user entered report query shown in the header like this (BTW: It's Norwegian language i the query dialog/report, but you will figure out what I mean):




All you need is to create the "showHeader" method shown below and use it in the pageheader or wherever you need to see this information.

The Code:
display formLetterTxt showHeader()
{
   int i,j,CurFieldID;
   formLetterTxt headerInfo;
   str CurPName;

   for (i=1;i<=element.query().dataSourceCount();i++)
   {
      for (j=1;j<=element.query().dataSourceNo(i).rangeCount();j++)
      {
         CurFieldID=fieldname2ID(element.query().dataSourceno(i).table(),element.query().dataSourceNo(i).range(j).name());
         CurPName=FieldID2pName(element.query().dataSourceno(i).table(),curFieldID);
         headerinfo+=(headerinfo ? '\n' : '')+curPName+':'+ element.query().dataSourceNo(i).range(j).value();
      }
   }

   return strfmt("Rapportparametere benyttet:\n%1",headerinfo);
//Translates to:   return strfmt("Rapportparams used:\n%1",headerinfo);
}

Monday, February 27, 2012

Ax2012

I just installed and configured the VirtualBox from Oracle and the Dynamics AX 2012 demo after these instructions. It worked great, so now I have a working AX2012 test and training setup.

Friday, February 17, 2012

Get the callstack without the need of breakpoints

Normally, when you debug a issue, you use the debugger and breakpoints. That's fine, but sometimes you need to debug bugs that triggers randomly and you need to check the call stack for more information or even log the call stack to a table for later inspections. Here is how to do that. Create a new class or use your existing tool class and insert the following method:

static str getCallStack(boolean _showInfo = false)
{
   xSession xSession = new xSession();
   container callStack = xSession::xppCallStack();
   str text;
   int i;

   str convert2string(anytype _value, int variation = 0)
   {
      switch (typeof(_value))
      {
         case Types::String :
            return _value;
         case Types::Real :
            return num2str(_value, 10, 4, 1, 0);
         case Types::Integer :
            return int2str(_value);
         case Types::Date :
            if (variation == 0)
               return date2str(_value, 321, 2, 3, 2, 3, 4 );
            else if (variation == 1)
               return date2str(_value, 321, 2, 1, 2, 1, 2 );
         case Types::Enum :
               return enum2str(_value);
      }
   }

   for (i = 1; i < conLen(callStack); i+=2)
   {
      if(_showInfo)
         info( "Path: " + convert2string(conPeek(callStack, i)) + " Line: " + convert2string(conPeek(callStack, i+1)));

      text += ("Path: " + convert2string(conPeek(callStack, i)) + " Line: " + convert2string(conPeek(callStack, i+1)) + "\n");
   }
   return text;
}


Then in your class where you want to get the call stack:

Example
...
   try
   {
      ...
   } catch (..)
   {
       MyToolClass:: getCallStack(true);
   }
 ...

BTW: If the code are executed in a thread or at the AOS, you should call getCallStack with false and use the returned string instead.

Thursday, February 16, 2012

Application environment

Sometimes when I'm working on a new customer and I don't know the Ax environment, I run this job. Check out the xInfo class for more information:

static void environment(Args _args)
{
   ;

   info( xInfo::buildNo() + ' - '
     + xInfo::compilationDate() + ' - '
     + xInfo::dbName() + ' - '
     + xInfo::osName() + ' - '
     + xInfo::productName() + ' - '
     + xInfo::releaseVersion());

   info(xinfo::componentName());

   info(xinfo::configuration());

   info(xInfo::directory(DirectoryType::Bin));
}