« »

search

Art Of Creation – Dynamics AX Blog

 The everyday life of a Dynamics AX developer

  • Append text from one file to an other

    October 31, 2009 at 08:28  (3 comments)

    This method will append all text from the original file to the destination file.
    While this is a very easy task, the method shows many of the things you come across when you are working with files in AX, like:

    – Using the #File macro
    – Asserting FileIOPermission to be able to access files
    – Asserting InteropPermission to be able to use .NET Interop
    – Using a set to assert multiple permissions at once
    – Using .NET Clr Interop in AX (better than winapi and winapiserver)
    – Optional cleaning up after you’re done using reverAssert()

    void AppendFileToFile(FileName original, FileName distination)
    {
        #File
        FileIOPermission    FileIOPermissionA   = new FileIOPermission(distination, #io_append);
        FileIOPermission    FileIOPermissionR   = new FileIOPermission(original, #io_read);
        InteropPermission   InteropPermission   = new InteropPermission(InteropKind::ClrInterop);
        Set                 permissionset       = new set(types::Class);
        ;

        // create permissionset
        permissionset.add(FileIOPermissionA);
        permissionset.add(FileIOPermissionR);
        permissionset.add(InteropPermission);
        // assert permissions
        CodeAccessPermission::assertMultiple(permissionset);
        // append text from source file to destination file
        System.IO.File::AppendAllText(distination, System.IO.File::ReadAllText(original));

        // limit the scope of the assert
        CodeAccessPermission::revertAssert();
    }

    Because all permissions are taken care of, this code will run client side as well as server side.

  • Check up on compilation status

    October 30, 2009 at 19:32  (2 comments)

    A (little) trick in between. I thought everyone was using this method, but I apparently I was wrong, so here you go.

    Doing a full compile takes a long time, and because of that, it’s handy to be able to check how much of the process is done and how much remains.
    Luckily, when doing a full compile, the Compiler Output form appears at the bottom of the screen where you can see what is currently being compiled.

    The only problem is that most of the time, the AX client hangs and is not responsive during the compilation process, so you can’t see that information.

    The solution to this is to press Crtl + Break.
    You will see a window that says:

    Are you sure that you want to cancel this operation?
    To start the Debugger for Microsoft Dynamics, press and hold SHIFT while you click No.

    While this screen is active, the Compiler Output form will update so you can check up on the status. When you’re done, be sure to click “No” to resume the full compile. Don’t click “Yes” because then the compilation will not resume and you’ll have to start again.

  • Dynamics AX Wallpaper

    October 29, 2009 at 21:26  (3 comments)

    I was looking for a Dynamics themed wallpaper for my desktop, and couldn’t find one, so I made one myself.
    It’s so much nicer to have something AX related on your desktop when you’re doing demo’s and such.

    Dynamics Ax Wallpaper 1920x1080

    Dynamics Ax Wallpaper 1920x1080

    If you like it, don’t hesitate to use it. It’s free of logo’s (except for the Dynamics one of course), so you can put your own ones on it.

  • An instance of Microsoft Dynamics AX Configuration is already running

    October 28, 2009 at 19:00  (1 comment)

    When you start the Microsoft Dynamics AX Configuration Utility, you might get the following message:

    An instance of Microsoft Dynamics AX Configuration is already running. Only one instance can be run at a time.

    You get this message because, obviously, the utility is already running, and you can’t start two instances. So, just click ok, look in the task bar for the Configuration Utility, and go from there.

    But… but… There is no AX configuration utility active!
    Most likely, you are logged into a machine using remote desktop, where an other user has the configuration utility active.

    You can check this in using the Task Manager.
    1. Right click the Task Bar and start the Task manager,
    2. On the processes tab, make sure you see the processes for all users (there’s a checkbox or a button at the bottom) ,
    3. Now look for the process called AxCliCfg.exe,
    4. You can contact the user to ask him to close the Configuration Utility, or you can kill the process yourself.

  • Application file extensions

    October 27, 2009 at 20:00  (6 comments)

    Dynamics AX uses a lot of file extensions, but luckily, there is a logic to them, so you can easily identify their purpose.

    Most of these files are located in the application folder (AX 2009):
    C:\Program Files\Microsoft Dynamics AX\50\Application\Appl\[your_application]

    The extensions have 3 characters:
    The first character indicates the owner of the file:

    a: application
    k: kernel

    The second character indicates the content of the file:

    l: label
    o: object
    t: text
    d: developer documentation
    h: help

    And the third character indicates the type of file:

    d: data
    i: index
    c: cache
    t: temporary

    Using this logic, we can easily name all file extensions, and understand their purpose.

    In the application folder:
    ALD extension: Application Label Data files
    These files contain the labels and label comments for a specific language of a label file.

    ALC extension: Application Label Cache files
    These files contain the application label cache. These files can be deleted when the AOS is stopped.

    ALI extension: Application Label Index files
    The .ali files contain an index to the .ald files. These files can be deleted when the AOS is stopped.

    ALT extension: Application Label Temporary files
    These files contain new labels before they are committed to the .ald file.

    AOI extension: Application Object Index file
    The AOI file contains an index to the AOD files. You can delete this file when the AOS is stopped. Be sure to delete this when you have copied layers from one AX installation to an other.

    ADD extension: Application Developer Documentation Data files
    These files contain the documentation that is found under the Application Developer Documentation node. These files are localized, just like label files.

    ADI extension: Application Developer Documentation Index files
    This is the index to the ADD file.

    AHD extension: Application Help Data files
    The AHD file contains the documentation aimed at the end user. In the AOT, this is found in the “Application Documentation” node.

    AHI extension: Application Help Index files
    This is the index to the AHD file.

    AOD extension: Application Object Data file
    This is the ‘AX layer file’, each of these files represents one layer.

    KHD extension: Kernel Help Documentation files
    These files contain the kernel help documentation you can find in the AOT in the tree node System Documentation.

    KHI extension: Kernel Help Index files
    The KHI file is the index to the Kernel Help file.

    Located in Server/bin:
    KTD extension: Kernel Text Data file
    This file contains system text strings. These are used in the interface of AX and for system messages.

    KTI extension: Kernel Text Index file
    This is the index to the KTD file.

    Client side (not following the naming logic):
    AUC extension: Application Unicode Object Cache file (as from AX 4.0)
    This file is created on the client side, and is used to improve performance by caching AX objects. When you are in the situation where an AX client keeps using ‘old code’, or where something works on one client and not on the other, removing the AUC file might be the solution.
    You can find this file in the directory C:\Documents and Settings\[USERNAME]\Local Settings\Application Data for xp, or C:\Users\USERNAME\AppData\Local for vista.
    More information about object caching on Axaptapedia

    AOC extension: Axapta Object Cache file (Untill Axapta 3)
    This is the ‘old’ version of the AUC file but serves the same purpose.

    Further reading:
    MSDN: Application files architecture
    DAXcoder: Axapta Filename Extension Naming Conventions

  • While select firstonly

    October 22, 2009 at 22:11  (2 comments)

    Some months ago, I had this ‘aha! moment’, when I saw something like this in my code:

    while select firstonly custTable
    {
        // do something
    }

    I had modified a singe select statement into a loop, but forgot to remove the ‘firstonly’ qualifier.
    Then it hit me that the over example is actually the same as writing the following:

    select firstonly custTable;

    if(custTable.recId)
    {
        // do something
    }

    I really liked the idea of the while loop, and I think I’ve used it once or twice where I thought it was appropriate, until I bothered Googling the statement. You get 9 results from Google, which isn’t much, and the first is on msdn:

    Do not use while select firstOnly.

    However, this result is followed by 2 others from msdn (1 and 2), where they do use “while select firstonly”. The last one, is on a page titled “Top Best Practices to Consider”.

    I can think of a couple of reasons why you shouldn’t use such a statement, one of which is performance, and an other readability, but apparently, Microsoft uses it anyway. Also, you can’t use it in cases where you need an ‘else’ branch.

    I, for one, have changed my code and won’t be writing code like this anymore. “While select firstonly” was short lived.

  • Five nice-to-haves in Dynamics AX

    October 20, 2009 at 21:06  (2 comments)

    Here a some functionalities that I think are nice-to-haves in future versions of AX from a developer point of view. I hope they make sense :).

    1. Select table where field in set
    Consider a situation where you have a set or container filled with recId’s. When you want to loop all records that have one of these recId’s, it would be nice to be able to write something like this:

    Set         set = new Set(Types::Int64);
    CustTable   custTable;
    ;

    set.add(5637166082);
    set.add(5637166083);

    while select custTable
    where custTable.RecId IN set // this will not compile!
    {
    // do stuff
    }

    The only problem is that there is no ‘in’ operator in AX. You will either have to loop the set and select each record one at the time, or you’ll have to use the Query and QueryBuildRange classes to make this work.
    The above example would be much nicer in my opinion.

    2. Throwable exception classes
    It would be nice to be able to create your own exceptions.
    Java, for example, has Throwable and Exception classes that can be extended.
    I won’t say that I completely understand these java classes (I’m not a Java guy), but I believe it would force developers to catch only exceptions they can handle, and not just all exceptions.
    It would also make it possible to have more information as to why an exception has occoured when you catch it.

    3. Try – catch – finally
    This is a classic: the try-catch-finally is not supported in AX. When we look at C# for example, a try-catch can have a ‘finally’ block at the end. The code in this block is always executed, even if an exception occoured.

    4. Events using CLR Interop
    CLR Interop does not support event handling in AX. It would be nice to be able to assign an event handler to an event, so an event can trigger functionality in AX without complicated workarounds involving .NET wrapper classes, infinite loops, services or other creative solutions. (I’m thinking about things like FileSystemWatcher).

    5. Code refactoring
    When you rename an object in AX (Table, field, class, method, etc), there is no refactoring option. You have to manually rename all other instances of that object.
    For example: it would be nice if, when you rename a field, AX had the option to automatically update all methods, forms, etc, where this field was used.

  • Dynamics AX and Google

    September 9, 2009 at 13:00  (no comments)

    This is an article I wanted to write for some time now, and it’s about two things: Dynamics AX, and Google.
    The goal here is to try to know what lives in the Dynamics AX world.

    A nice feature Google search has is autocomplete. It comes in handy when you have to write hard to write words, or when you just want to search faster.

    It’s also a nice way to discover what people are querying for about a certain subject, for example Dynamics AX. Here’s a list of item Google suggests when you type “Dynamics AX ” in the search box.

    dynamics ax 2009
    dynamics ax jobs
    dynamics ax training
    dynamics ax certification
    dynamics ax modules
    dynamics ax blog
    dynamics ax workflow
    dynamics ax 4.0
    dynamics ax aif
    dynamics ax demo

    I don’t want to make an opinion piece out of this, so I’ll just break this up in groups without further comment.

    General: 2009, 4.0, modules & demo
    Jobs and Certification: training, certification & jobs
    Functionality: workflow & AIF
    Community: Blog

    While you don’t know the context of these queries, it’s nice to know what people are interested in.
    Try it for a few subjects, and you might find out some interesting things.

  • Site news: AX link page

    August 31, 2009 at 21:49  (no comments)

    Hi all,

    A new page has been added: AX links.
    Be sure to check it out, there are some really helpful and interesting links in that list.

    If you have bookmarks that you would like to share that are related to AX, just comment and I’ll add them to the list.

  • Editorscripts: create parm method from class declaration

    August 27, 2009 at 13:55  (4 comments)

    I’ve always found it annoying that when you want to create a parm method using the editorscripts, you have to fill in two fields on a dialog (variable name and type). Most of the time, you’ve already declared the variable in the class declaration of your class, so it would be nice if you could just right click on that and create a parm method from there.

    Below is a (quick and dirty) editorscript that allows you to do that.
    For AX 2009:

    public void template_method_parmfromCD(Editor editor)
    {
        int endLine   = editor.selectionEndLine();
        str line;
        str firstCol;
        str secondCol;
        int linecount;
        str source;
        container cont;
        XppSource xppSource;
        TreeNode tn;
        TreeNode childNode;

        boolean contains(str s, str findStr)
        {
            if(strscan(s, findStr, 1, strlen(s)) > 0)
                return true;

            return false;
        }

        str replace(str s, str findStr, str replStr)
        {
            int pos = strscan(s, findStr, 1, strlen(s));

            while(pos > 0)
            {
                s = strdel(s, pos, strlen(findStr));
                s = strins(s, replStr, pos);

                pos = strscan(s, findStr, pos + strlen(replStr), strlen(s));
            }
            return s;
        }
        ;

        editor.firstSelectedLine();
        while (editor.moreLines() && endline > editor.lineNo())
        {
            line = strltrim(editor.getLine());
            while(contains(line, "  " ))
            {
                line = replace(line, "  ", " " );
            }

            cont = str2con(line, " ");

            firstCol = conpeek(cont, 1);
            secondCol = conpeek(cont, 2);
            secondCol = strrem(secondCol, ";=");

            editor.nextSelectedLine();

            tn = EditorScripts::getApplObjectNode(editor);
            if(firstCol != "0" && secondCol != "0")
            {
                if(!tn.AOTfindChild(strfmt("parm%1", strupr(substr(secondCol,1,1))+substr(secondCol,2,strlen(secondCol)))))
                {
                    if(tn.AOTfindChild("Methods"))
                        tn = tn.AOTfindChild("Methods");

                    childNode = tn.AOTadd(strfmt("parm%1", strupr(substr(secondCol,1,1))+substr(secondCol,2,strlen(secondCol))));

                    xppSource = new XppSource();
                    source = xppSource.parmMethod(firstcol,secondCol);
                    childNode.AOTsetSource(source, false);
                    tn.AOTsave();
                }
                else
                {
                    error(strfmt("Parm method %1 already exists", strfmt("parm%1", strupr(substr(secondCol,1,1))+substr(secondCol,2,strlen(secondCol)))));
                }
            }
        }
    }

    For AX 2012 (thanks to Alex):

    public void template_method_parmfromCD(Editor editor)
    {
         int endLine   = editor.selectionEndLine();
         str line;
         str firstCol;
         str secondCol;
         int linecount;
         str source;
         container cont;
         XppSource xppSource;
         TreeNode tn;
         TreeNode childNode;

         boolean contains(str s, str findStr)
         {
             if(strscan(s, findStr, 1, strlen(s)) > 0)
                 return true;

             return false;
         }

         str replace(str s, str findStr, str replStr)
         {
             int pos = strscan(s, findStr, 1, strlen(s));

             while(pos > 0)
             {
                 s = strdel(s, pos, strlen(findStr));
                 s = strins(s, replStr, pos);

                 pos = strscan(s, findStr, pos + strlen(replStr), strlen(s));
             }
             return s;
         }
         ;

         editor.firstSelectedLine();
         while (editor.moreSelectedLines() && endline > editor.currentLineNo())
         {
             line = strltrim(editor.getLine());
             while(contains(line, "  " ))
             {
                 line = replace(line, "  ", " " );
             }

             cont = str2con(line, " ");

             firstCol = conpeek(cont, 1);
             secondCol = conpeek(cont, 2);
             secondCol = strrem(secondCol, ";=");

             editor.nextSelectedLine();

             tn = EditorScripts::getApplObjectNode(editor);
             if(firstCol != "0" && secondCol != "0")
             {
                 if(!tn.AOTfindChild(strfmt("parm%1", strupr(substr(secondCol,1,1))+substr(secondCol,2,strlen(secondCol)))))
                 {
                     if(tn.AOTfindChild("Methods"))
                         tn = tn.AOTfindChild("Methods");

                     childNode = tn.AOTadd(strfmt("parm%1", strupr(substr(secondCol,1,1))+substr(secondCol,2,strlen(secondCol))));

                     xppSource = new XppSource();
                     source = xppSource.parmMethod(firstcol,secondCol);
                     childNode.AOTsetSource(source, false);
                     tn.AOTsave();
                 }
                 else
                 {
                     error(strfmt("Parm method %1 already exists", strfmt("parm%1", strupr(substr(secondCol,1,1))+substr(secondCol,2,strlen(secondCol)))));
                 }
             }
         }
    }

    Some code from Greg Pierce’s awesome String class was used for the inner methods.
    I tested it on classes, form and reports, and it works very well.

    To install this editorscript, copy the code above in a new method of the class EditorScripts.
    To use it, in the classDeclaration, simply select one or more declarations, then right click and choose Scripts – template – method – parmfromCD.

  • Remove leading zeros

    August 3, 2009 at 10:49  (no comments)

    Sometimes, you’ll want to add leading zeros, but other times, you’ll have to remove leading zeros from a string.
    Here the code that does just that:

    static void RemoveLeadingZeros(Args _args)
    {
        str text = "0000A1337";
        ;

        while(substr(text, 1, 1) == "0")
        {
            text = substr(text, 2, strlen(text) - 1);
        }
        info(text);
    }

    The above example will work for any alphanumeric string.

    When you’re sure you’re dealing with numeric strings, you can use this example:

    static void RemoveLeadingZeros2(Args _args)
    {
        str text = "00001337";
        ;

        if(strrem(text, "0123456789") == "")
            info(int2str(str2int(text)));
        else
            error("text is not numeric");
    }

    You should build in a check because the str2int() function doesn’t throw an error when the input isn’t numeric.

    An example I found online also removes leading zeros from a string, but it fails if the first character after the zeros isn’t numeric:

    static void RemoveLeadingZeros3(Args _args)
    {
        str text = "0000A1337"; // doesnt work
        // str text = "00001A337"; // works
        ;

        info(strdel(text, 1, strfind(text, "123456789", 1, strlen(text)) - 1));
    }

    Conclusion:
    The first example works best, but you should still be careful when converting the resulting string to other types, as you could get unexpected results.

  • Writing in the event log from Dynamics AX

    June 19, 2009 at 13:14  (2 comments)

    Writing to the event log in Windows using AX is very easy when you use the EventLog class from the System.Diagnostics namespace. The following job demonstrates how to use the EventLog class.

    static void EventViewer(Args _args)
    {
        System.Diagnostics.EventLog eventlog;
        #Define.LogSource("Dynamics AX")
        #Define.LogName("Dynamics AX Log")
       
        ;
        // check if the log already exists
        if(!System.Diagnostics.EventLog::SourceExists(#LogSource))
        {
            // create new log
            System.Diagnostics.EventLog::CreateEventSource(#LogSource, #LogName);
        }

        eventlog = new System.Diagnostics.EventLog();
        eventlog.set_Source(#LogSource);

        // write info entry
        eventlog.WriteEntry("Just writing in the event viewer.");
        // write error entry
        eventlog.WriteEntry("Error! Please check the stack trace below. \n\n" +
            con2str(xSession::xppCallStack()), System.Diagnostics.EventLogEntryType::Error);
        // write warning entry
        eventlog.WriteEntry("Job finished." , System.Diagnostics.EventLogEntryType::Warning);
       
        info("Check the event viewer!");
    }

    A possible use for this is when monitoring batch jobs.
    Tested using AX 2009, XP Pro.

  • Error code 122 while exporting xpo

    June 5, 2009 at 15:12  (no comments)

    While exporting code from Dynamics Ax to an xpo file, I received the following error:

    Error in file: C\DOCUME~1\SRV_TR~1\LOCALS~1\Temp\$tmp00040005$ while writing in record = D8AA0
    Windows error: =
    Error code: 112 = Unknown Error

    Error code 122 means (msdn):

    ERROR_DISK_FULL: There is not enough space on the disk.

    The problem here is that the AOS is trying to create a file, but there is not enough space on the hard disk to do that.
    You can solve this problem by freeing up disk space on the AOS. After you did that, exporting will work again.

  • Problem solving in AX

    May 13, 2009 at 21:04  (10 comments)

    Sometimes, when developing, AX doesn’t work as expected, or behaves weird.
    Here are some of the things you can try if you run out of ideas, roughly in the order I do:

    Try again
    You probably already did, but make sure you can reproduce the problem. If it only occurred once, it’s not a problem.

    Check your code again
    Check your code carefully for errors, and maybe ask a colleague’s opinion.

    Compile
    Your project might contain compile errors, so compile it to be sure.

    Close the debugger
    Sometimes, when the debugger is active, AX will keep executing ‘old’ code. Close the debugger to make sure the latest code is executing.

    Compile forward
    When you have modified a class that is inherited by other classes, you might want to compile forward this class.

    Synchronize data dictionary
    You may have made changes to application objects that haven’t been synchronized with the database. Open the AOT, right click on the Data Dictionary node and choose Synchronize.

    Restart AX client
    Simple as that, close the AX client and start it again.

    Reset usage data
    Go to options screen (AX button > Extra > Options) and click the Usage Data button. Click reset to remove this data.

    Check the application event log for clues
    Open the event viewer on the AOS to see if the AOS service has logged something in it. Messages here can help you a great deal. You can also check the event log on the database server or your client pc.

    Google it
    If you receive an error, just copy and paste it in Google. Most likely you are not the only one having that problem.

    Check your client version
    Check your AX client version. You might for example be connecting to a SP1 application with an SP0 client. You can check this in the about screen: AX button > Help > About. The kernel version indicates the client version, below that is the application version.

    Refresh AOD, Dictionary and Data
    You can flush cashed information using three option in the Tools > Development tools menu: refresh AOD, refresh Dictionary and refresh Data. This can be useful when you just imported an xpo file, or when you are developing for the enterprise portal.

    Delete AUC file
    The application Unicode object cache file, if there is one, is located at C:\Documents and Settings\[USERNAME]\Local Settings\Application Data for xp, or C:\Users\USERNAME\AppData\Local for vista. Delete this file while the AX client is closed.

    Check if other users are having the same problem
    Knowing whether you are the only one that’s having that problem or if it’s a general problem is a big step towards solving the problem. For example, if you alone have the problem, restarting the AOS probably won’t solve it, but removing usage data might.

    Check security settings
    When only some users have a problem, big changes are that it has something to do with security settings. Security can be set up from Administration > Setup > Security, on the Permissions tab.

    Check configuration key setup
    Some features of AX won’t work if a configuration key is disabled, be aware of this.

    Full compile
    Open the AOT, right click the AOT node and select compile.

    Restart AOS
    Sometimes restarting the AOS solves your problem just fine. If you can, it’s worth the try as this doesn’t take long.

    Remove .aoi file
    When the AOS is stopped, you can delete the .aoi file from the application files. This file will be rebuilt when the AOS starts.

  • Error 1740: The endpoint is a duplicate

    May 6, 2009 at 13:42  (1 comment)

    Today, I came across the following error when trying to start an AOS:

    Error 1740: The endpoint is a duplicate

    This error occurs when the port that is specified in the server configuration of the AOS is in use by another process.
    You’ll also find an entry in the event log on the AOS:

    Object Server 03: RPC error: The Dynamics Server could not be started because TCP Port 2752 is already in use.

    To figure out what process is using the port, you can use the Netstat command on the server. You’ll find something like this if an AOS is using the port:

    TCP AOSServer:2752 DBServer.domain:ms-sql-s ESTABLISHED

    It is possible that an other process is using that port, so either terminate that process or restart the AOS that’s occupying the port.
    When you have more then one AOS on the server, the problem is figuring out what AOS is using the port.
    You can search all server configurations for the port, but in my case, an AOS was connected to the wrong port because of a bug of some sort, so I used a program called CurrPorts.
    CurrPorts shows you more information than the Netstat command, and gives you the option to terminate a TCP/IP connection.
    I only needed to restart the AOS that was using the wrong port and the problem was solved.

  • « Previous Page

    Next Page »

     

Best value on tickets: wickedthemusicaltickets.top 100% guaranteed tickets: luke bryan concert tickets Discount Broadway Tickets - hamiltonmusicaltickets.top View dates for upcoming Billy Joel concert tour - http://billyjoeltourtickets.top Discount Tickets for Broadway, find cheap Hamilton Broadway Tickets Tickets On Sale For All Dates - Eric Church Tour 2017 Major League Baseball Tickets. Get your SF Giants Tickets and save Search all sellers and save on cheap Indians Tickets

Wordpress // Photon theme // Copyright © Klaas Deforche

 

Loading Comments...