AX/D365 SSRS Report: “: Error 1 : Format is invalid. “

Problem: When modifying a SSRS report I received the following error at compile time. “Error 1 : Format is invalid. InvalidIdentifier \SSRS Reports\Reports\[ReportName]”

Solution: It turns out if you copy and paste expressions with functions in them, Visual studio will create an expanded version of them with the full function namespace e.g.
=Format(Fields!MyDateTimeField.Value, “dd/MM/yyyy hh:mm:ss tt”)
becomes
=Microsoft.VisualBasic.Strings.Format(Fields!MyDateTimeField.Value, “dd/MM/yyyy hh:mm:ss tt”)

Simply removing this additional namespace seems to resolve the issue.

Hope my pain helps someone!

AX DB Restore Scripts #6 – SMTP Server and DMF Folder

Recently I started creating a list and a series of posts on SQL scripts I use when restoring Dynamics AX databases from one environment to another, typically from production to QA or development.

We have so far discussed a number of configurations that must be changed for the new system to operate effectively and starting yesterday we moved onto exploring more optional configurations.

Today we will cover two of these items namely re-configuring the outgoing SMTP server in AX and configuring the settings for the DMF working folder.

Note: In my experience the SMTP server will most likely not change between a production and development server, but you may need to reconfigure it if moving to a new domain etc. Similarly it will work to use the same DMF shared folder between PROD and DEV, however I would recommend changing this to keep the data 100% separate.

These two configurations are located in the Dynamics AX 2012 client under the following paths.
1. SMTP Server, accessed via System Administration -> Setup -> System -> E-mail parameters.EmailServer

2. Data import, export framework shared working directory. Accessed via “Data import export framework -> Setup -> Data import export framework parameters”
DMF

To update these 2 settings above we need to do the following:

1. Update the SysEmailParameters table to update the SMTP server name (and additional login parameters)
2. Update the DMFParameters table to reflect the new shared folder path.

The following SQL code will accomplish the above. I have parameterised the SQL for easier reuse or adjustment.

---Outgoing Email Settings---
Declare @SMTP_SERVER varchar(100) = 'smtp.mydomain.com' --Your SMTP Server
Declare @SMTP_PORT int = 25

---DMF Folder Settings ---
Declare @DMFFolder varchar(100) = '\\[YOUR FILE SERVER]\AX import\'

---Update Email Parameters---
Update SysEmailParameters set SMTPRELAYSERVERNAME = @SMTP_SERVER, @SMTP_PORT=@SMTP_PORT
---Update DMF Settings---
update DMFParameters set SHAREDFOLDERPATH = @DMFFolder 
where SHAREDFOLDERPATH != @DMFFolder --Optional to see affected rows

I hope this assists you and will be useful in your management of your AX environments.

View next – AX DB Restore Scripts #7 – Setting Email Templates and User Email Addresses

View Previous – AX DB Restore Scripts #5 – Configure Service Accounts and Help Server

Back to List

AX DB Restore Scripts #5 – Configure Service Accounts and Help Server

Last week I embarked on a series of posts on DB restore scripts for Dynamics AX by creating a list of items in your AX database that need to be updated/reconfigured when restoring a database from a production environment to a development or QA one.

So far we have covered the majority of the most critical issues to fix when doing a DB restore, so from today on most of the scripts are basically optional. They are optional for one of the following reasons: 1. It may be common to have the same configuration in both live and dev, yet in some circumstances they may differ e.g. Business connector may remain the same if you are restoring from live to dev, but not from live to a demo VPC.
2. The data is correct but for safety or security you may want to manipulate it for a development environment. E.G. Changing all email templates to clearly indicate the source is from a dev system.

Today we will cover two topics namely re-configuring the service accounts in AX and configuring the AX help server URL.

In the Dynamics AX 2012 client, the configurations that we are going to look at are:
1. System Service Accounts, accessed via System Administration -> Setup -> System -> System service Accounts

ServiceAccounts

2. Batch Jobs, accessed via System Administration -> Setup -> System -> Help system parameters
Helpserver

To update the settings above we need to do the following:

1. Update the SYSBCPROXYUSERACCOUNT table to reflect the business connector user’s SID, networkdomain and network alias. For this step you will need to find out the SID of the business connector either by setting it manually the first time and then running select SID from SYSBCPROXYUSERACCOUNT where NETWORKDOMAIN='[yourdomain]’ and NETWORKALIAS='[yourbcuseralias]’ or follow one of the suggestions over here http://blogs.msdn.com/b/gaurav/archive/2014/06/03/get-sid-of-the-object-registry-wmic-powershell.aspx
2. Update the SYSWORKFLOWPARAMETERS table to reflect the userId of the workflow execution account.
3. Update the SYNCPARAMETERS table to reflect the userId of the Microsoft Project server synchronization service account.
4. Update SYSGLOBALCONFIGURATION to reflect new help server URL if necessary.

Notes:
1. If you are wanting to use an Alias/Network domain combination for either of the two execution accounts, I would recommend setting them manually in AX as they create users and permissions automatically when you do this. 
2. The above script assumes that execution accounts you are setting exist in the new system and have the necessary permissions.

The following SQL code will accomplish the above. I have parameterised the SQL for easier reuse or adjustment.

---BC Proxy Details ---
Declare @BCPSID varchar(50) = '[BCPROXY_SID]'
Declare @BCPDOMAIN varchar(50) = '[yourdomain]'
Declare @BCPALIAS varchar(50) = '[bcproxyalias]'
---Service Accounts ---
Declare @WFEXECUTIONACCOUNT varchar(20) = 'wfexc'
Declare @PROJSYNCACCOUNT varchar(20) = 'syncex'
---Help Server URL---
Declare @helpserver varchar(200) = 'http://[YOURSERVER]/DynamicsAX6HelpServer/HelpService.svc'

---Set BCPRoxy Account---
update SYSBCPROXYUSERACCOUNT set SID=@BCPSID, NETWORKDOMAIN=@BCPDOMAIN, NETWORKALIAS= @BCPALIAS
where NETWORKALIAS != @BCPALIAS --optional to display affected rows.
---Set WF Execution Account---
update SYSWORKFLOWPARAMETERS set EXECUTIONUSERID=@WFEXECUTIONACCOUNT where EXECUTIONUSERID != @WFEXECUTIONACCOUNT
---Set Proj Sync Account---
update SYNCPARAMETERS set SYNCSERVICEUSER=@PROJSYNCACCOUNT where SyncServiceUser!= @PROJSYNCACCOUNT
---Set help server URL---
update SYSGLOBALCONFIGURATION set value=@helpserver where name='HelpServerLocation' and value != @helpserver

I hope this assists you and will be useful in your management of your AX environments.

View Next – AX DB Restore Scripts #6 – SMTP Server and DMF Folder

View Previous – AX DB Restore Scripts #4 – Reconfigure batch jobs

Back to List

Free: AN INTRODUCTION TO DYNAMICS AX 2012 (Dynamics AX Companion Guides)

2015-07-24_1435Its not really my habit in my blog to re-post or re-blog other users content, but rather to write up my own findings as I explore Dynamics AX. However this post is a bit of a worthy exception.

If you have been in AX for an period of time you have most likely heard of Murray Fife and his very practical Companion guides to Dynamics AX. Right now you can download his “AN INTRODUCTION TO DYNAMICS AX 2012” for free over here. It is highly useful material for anyone new to AX or even old hats looking for some new easy to use tips and tricks. I’ve been compiling some introductory basic training material for our company and this book will go along way in assisting me with this!

Thank you Murray Fife for this awesome content.

See his original post over here too.

https://www.linkedin.com/pulse/free-prize-download-introduction-dynamics-ax-2012-murray-fife?trk=prof-post

Update: Unfortunately this was only a limited time offer, but I would still encourage you to get hold of this book either from Murray Fife’s website http://www.dynamicsaxcompanions.com/ or from amazon  Here

Beware the “Catch”

Recently while debugging some legacy code I came across the following interesting observation regarding transaction scopes (ttsbegin, ttscommit) and the exception handling surrounding it. While walking the legacy code was observing very strange and unexpected behaviour and after some online investigation i found the following statement from Microsoft:

“When an exception is thrown inside a ttsBeginttsCommit transaction block, no catch statement inside that transaction block can process the exception. Instead, the innermost catch statements that are outside the transaction block are the first catch statements to be tested.”
(
https://msdn.microsoft.com/en-us/library/aa893385.aspx)

In its simplest form this means that for the following code:

 try
    {
        ttsBegin;
        try
        {
            throw error("Thrown Error");
        }
        catch (Exception::Error)
        {
            error("Inside Error");
        }
        ttsCommit;
    }
    catch (Exception::Error)
    {
        error("Outside Error");
    }

Prints the following results:
2015-07-23_0801

Now when it comes to a simple block of code like above one may say “Well that is simply silly coding”, however it becomes harder to anticipate results when that inner try…catch is within a method somewhere deeper inside the call stack (perhaps in standard code somewhere) e.g.

    void innerFunction()
    {
        try
        {
            ttsbegin;
            throw error("Thrown Error");
            ttscommit;
        }
        catch (Exception::Error)
        {
            error("Inside Error");
        }
    }
    
    try
    {
        ttsBegin;
            innerFunction();
        ttsCommit;
    }
    catch (Exception::Error)
    {
        error("Outside Error");
    }

Further more if your inner exception does cleanups or logging of information this will not happen by carelessly adding ttsBegins and ttsCommits around the calling code E.G. “writeErrorLog” will never be called in the following function regardless of what the writer of “innerFunction” does if the writer of the caller adds TTSBEGIN AND COMMIT

static void testTransactions(Args _args)
{
    void innerFunction()
    {
        while forUpdate select myTable
        {
            try
            {
            
                ttsBegin;
                if (someCondition)
                {
                    throw error("Throw Error");
                }
                else
                {
                    myTable.myField = "update";
                    myTable.update();
                }
                ttsCommit;
            }
            catch (Exception::Error)
            {
                writeErrorLog(strFmt("Failed on record %1", myTable.RecId));
                error("Inside Error");
            }
        }
    }
    
    try
    {
        ttsBegin;
            innerFunction();
        ttsCommit;
    }
    catch (Exception::Error)
    {
        error("Outside Error");
    }
}

I thought I would just paste these observations for anyone who like me has experienced this type of “strange behavior” in the past and didn’t know the exact reason and also as a warning to beware of the “Catch”.

Feel free to share your comments, observations and thoughts.

 

 

 

 

10. My checklist for debugging X++ code

As part of my series on “Things new X++ Developers Should know”. I have been writing a few basic howtos and checklists for new X++ Developers. These are really meant to be simple step by step guides to get new developers more productive by exposing the little secrets of the AX development that sometimes take years before discovering.

Today’s post is a checklist of things you need to have in place to ensure that you can debug X++ code.

  1. Enable debugging for your user. In an AX development window click on the tools menu item, then click options. Click on the development fast tab. Under debug mode set the option to “When Breakpoint”Enable_AX_Debugging
  2. Ensure your user is part of the local “Microsoft Dynamics AX Debugging Users” user group. On the machine which you are running the debugger on Edit your users and groups.
    2015-05-25_1545
    Expand the “Groups” section and double click on “Microsoft Dynamics AX Debugging Users”. Click “Add” and enter your domain name and click ok.
    2015-05-25_1546You will need to restart your user session by logging off and back on again
  3. Ensure the server is enabled for debugging (needed for serverside code). Open up the Microsoft Dynamics AX Server configuration console from Windows administrative tools. On the “Application Object Server” tab enable “Enable breakpoints to debug X++ code running on this server” and “Enable global breakpoints”
    Enable server breakpoints
  4. Enable client debugging options (optional/advanced for business connector debugging). In the Microsoft Dynamics Client configuration console in Windows administrative tools enable the following: “Enable user breakpoints to debug code in the Business Connector and Enable global breakpoints to debug code running in the Business Connector or client.
    2015-05-26_1449
  5. Ensure the debugger is installed on the client machine. Run the Microsoft Dynamics AX installer and ensure the “Debugger” (found under development tools is installed)
    2015-05-26_1452
  6. If your code is running in CIL:  You can either follow the steps listed on MSDN https://msdn.microsoft.com/en-us/library/gg860898.aspx or for simple debugging (i.e. logic errors) set your user to not run business logic in CIL via your user options form:
    2015-05-26_1510
  7. Finally and most obviously you need to create breakpoints. You can do this in three ways.
    1. Navigate to the line of code that you want to debug. Press F9
    2. Navigate to the line of code and press the “Red circle” on your toolbar.2015-05-26_1502
    3. Finally you can physically type “debug” in your code to create a breakpoint. However this will enable it for all users in the system, not just for yourself.
      2015-05-26_1503

I hope this checklist will help somebody stuggling with their debugging in AX. Please let me know if there are additional tips for debugging that this list may be missing.

For some additional details on debugging see MSDN:
https://msdn.microsoft.com/en-us/library/gg860898.aspx

Find all Menuitems Linked to a Form

For diagnostics purposes it is often useful to search the AOT for all objects matching cetain properties. For example you may want to find all display menutitems that are pointing to a specific form. The below job illustrates how to simply traverse the Display Menuitems node in the AOT to locate all items who’s “ObjectType” is “Form” and object is a specific form name. E.G. “PurchReqTable”.

static void FindMenuItemsForForm(Args _args)
{
 #AOT
 str find = "PurchReqTable";
 TreeNode root = TreeNode::findNode(#MenuItemsDisplayPath);
 TreeNode current;
 TreeNodeTraverser trav = new TreeNodeTraverser(root,false);
 
 current = trav.next();
 while (current)
 {
 if ((current.AOTgetProperty('ObjectType') == "Form") && (current.AOTgetProperty('Object') == find))
 info(strFmt("Found menuitem %1",current.AOTname()));
 current = trav.next();
 }

 

Search_AOT

Adapting this to search other nodes is as simple as changing the original node instantiation to search a different path as well as changing the AOTgetProperty() method to search through the properties relevant to you.

Happy Daxing

Original community post: https://community.dynamics.com/ax/f/33/p/161258/387257#387257

14. Using Alt+[Up/Down] to rearrange the order of elements in the AOT.

As part of my series on “Things new X++ Developers Should know”. I have been writing a few basic howtos for new X++ Developers. These are really meant to be simple instructions to get new developers more productive by exposing the little secrets of the AX development that sometimes take years before discovering.

Today is the simple trick of moving elements up and down in list in the AOT using your keyboard. E.G. Re-arranging fields in a grid control or field group. Sometimes the mouse re-arranging produces unexpeded results and is quite frankly much slower.

  • Simply highlight (click on) an element of an object that makes sense to re-order e.g. a column in a form grid.
  • While holding in the “ALT” key use the up and down arrow keys of your keyboard to move the object up and down in the list

Reorder_AOT_Elements

Notes on this functionality:

  • This functionality only works where it actually makes sense i.e. where where order actually matter like on grids and field groups. E.G. Moving your control above “methods” (in the screenshot) will have no effect and will automatically move it back down to directly below “methods” on re-opening the aot element.
  • This functionaly will do nothing on set elements in an Object e.g. “Methods”, “Datasources”, “Designs”, “Parts” etc…
  • If you’re a little OCD like myself and would like to re-arrange the fields (in the fields node) on a table object they will move when using Alt+[Up/down], but the change will not be permenant, even after saving. Field order doesn’t really make much difference in AX, apart from readability in the AOT. So if you want the primary key to be at the top of the list, then you must create it first (I haven’t found a workaround yet).
  • The same applies for ordering of methods in classes. The methods physically move but the change is not permenant
  • As above, even though you are physically able to, reordering the tables in the AOT makes no difference. They will always be revert to being alphabetical after re-opening the AOT.
  • Re-ordering objects in an AX development project does work! The elements will stay in the order that you arrange them.

 

 

8. Locate specific AOT object without scrolling

As part of my series on “Things new X++ Developers Should know”. I have been writing a few basic howtos for new X++ Developers.

Today’s post relates to quickly navigating to specific objects in the AOT without endless scrolling.

So often when working over the should of new developers or consultants exploring the AOT I see them scrolling endlessly or dragging the scrollbar back and forth for a while before finding the object they are looking for.

A common technique to navigate through lists in both Windows (e.g. My computer etc) and windows based environments (SQL management studio etc..) is to simply start typing the name of the object you are looking for. Windows automatically moves to the first object matching the sequence typed.

AX is by no means an exception to this rule. Simply click and expand the main node of the object you are looking for e.g. “Forms”
AOT Navigation Forms
and start typing E.G. “PurchReqT…..”
AOT_Navigation_Type_PurchReqT
As you type AX will move to the first object found matching what you have typed so far..
E.G. P moves to PartitionAdministration,  Pu to PurchArgreement etc….

There are some bonus features when using this in AX:
1. You can always see what you have typed so far by looking at the bottom left of your screenAOT_Navigation_Status_Bar
2. The typing timeout is long compared to applications like SQL etc where you need to have taken a speed typing course to get this right. As long as you still see the search term in the bottom you can just continue typing (this normally takes around 7 seconds or until you use your keyboard arrows or mouse to do something different

I know this may be a very obvious tip, but I’ve witnessed too many people taking forever to find objects by scrolling to not include this in the “Things new X++ Developers Should know” series.

Enjoy

 

4. Drill through to code from Info log

As part of my series on “Things new X++ Developers Should know”. I have been writing a few basic howtos for new X++ Developers.

Today’s post relates to quickly navigating to the source code from where an info log error, warning or information message is called from.  It took me a while to figure out that for many info log messsages you can simply double click on the message in the info log window and the code that called the message will be displayed for you.

E.G. If you see the normal error log icon or warning icons with a small arrow in the bottom left corner, you are normally able to double click the message to see the code behind it. These icons look like this:

InfoDrillDown2

Error Log

Infolog Info

Info Message

Warning Message

Warning Message

 

 

 

 

Simply Double click the message as below

InfoDrillDown

To be presented with the code that called it.

InfoLog5

 

NOTE 1: If you have your “Execute business operations in CIL” user option enabled, a lot of business logic like postings etc will not allow you to drill down.

NOTE 2: If the code calling the info message makes use of the SysInfoAction parameter, you will be taken to an alternate form specified by the developer and not the source code. (See Axaptapedia Article)

Adding code templates/shortcuts in AX 2012

If you’ve got any blocks of code that you use frequently, e.g. specific comment blocks, you can very easily add code short cuts in AX 2012 to auto-insert the them in to your X++ code.

For example you can setup AX to automatically create surrounding comment such as

whenever you type “mycom” and press the tab key.

How do you accomplish this. Very easily!

Step1: Locate the class EditorScripts in the AOT.
Step2: Create a new method with the format public void template_flow_[shortcut](Editor editor)
Step3: User the editor parameter to add code the code that you would like inserted. e.g. editor.insertLines(“\\test comment”);
Step4: Add your method to the case statement in the isApplicableMethod method in the section relating to template “editor scripts that does not apply to Macros” 

Thats it, now if you type your shortcut into any editor in AX and press tab, the “\\test comment” code will be inserted.

Here’s a full example method

The above creates the following output:

 

Repost from my old blog: https://workflowax.wordpress.com/2012/03/19/527/