Thursday, September 19, 2019

Parse JSON in pure X++

I decided to write a JSON parser in X++, because I couldn't find a useful implementation elsewhere. I wanted to avoid using external dll-based libraries.

It can handle strings, numbers (int and real), null-values and booleans. All kinds of linebreaks will be ignored.

It can be used like this:
str json = '{"foo": [1, 2, {"bar": 2}, {"bar": 3}]}';

AhkJSONObject ele = AhkJSONParser::parse(json);
AhkJSONArray arr = ele.get("foo");
AhkJSONObject obj = arr.get(3);
;

info('Demo 1: bar=' + obj.get("bar").strVal());
info('Demo 2: bar=' + AhkJSONParser::parse(json).getObjVal('foo').getArrayItem(3).getObjVal('bar').strVal());
info('Demo 3: bar=' + AhkJSONParser::parse(json).getObjVal('foo').getArrayItemWhere('bar', '3').getObjVal('bar').strVal());


Which will output:
Demo 1: bar=2
Demo 2: bar=2
Demo 3: bar=3

Please note the selection in demo 3, which makes it easy to select the correct array item. The project can be downloaded from the following url and is exported from AX 2009:
https://oc.ahkpro.dk/index.php/s/Q52BQ56zyrp2co8

The implementation is largely based on this python project:
https://github.com/eatonphil/pj/tree/master/pj

2020-01-20 update: I have updated the project with a few bugfixes, which should solve the two issues reported in comments.
2020-03-30 update: I have updated the project with a fix for parsing arrays as the outer type.

Friday, September 16, 2016

Fix space between menu items in the new AX7 menu

If you (like me) are bothered by the newly introduced space between menu items in the menu, then I have a solution :)


Screenshots

Original


With changed style

Procedure

Install the extension Stylish (or similar) in Chrome from the following link:
https://chrome.google.com/webstore/detail/stylish/fjnbnpbmkenffdnngjfgmeleoegfcffe?utm_source=chrome-ntp-icon

 And then set the style for cloudax.dynamics.com (or cloud.onebox.dynamics.com for local VM) to:

.modulesFlyout-last{
    margin-bottom: 0px !important;
}

.modulesFlyout-link{
    padding-bottom: 0px !important;
}

.modulesFlyout-LinkGroup.modulesFlyout-indent{
    margin-top: 0px !important;
    margin-bottom: 0px !important;
    padding-top: 1px;
    /*padding-bottom: 1px;*/
}

.modulesFlyout-LinkGroup:not(.modulesFlyout-indent){
    margin-bottom: 0px !important;
}

Thursday, June 16, 2016

Writing SSRS report directly to file / stream / byte array on AX7

If you ever need to write a report directly to a file, or for some reason get access to it before it is sent to the user, then you can replace your call to runReport on your SrsReportRun instance (similar code as when writing a report from code on AX 2012) with:

reportRun.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration());

SrsReportRunService reportRunService = new SrsReportRunService();
reportRunService.parmLocalMode(false);

reportRunService.preRunReport(reportRun.parmReportContract());


Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[]  parameterValueArray;
Map reportParametersMap;
reportParametersMap = reportRunService.createParamMapFromContract(reportRun.parmReportContract());
parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);
SrsReportRunPrinter printer = new SrsReportRunPrinter(reportRun.parmReportContract(), parameterValueArray);

printer.parmSrsProxy().parmReportExecutionInfo(executionInfo);

System.Byte[] reportBytes = printer.parmSrsProxy().renderReportToByteArray(reportRun.parmReportContract().parmReportPath(),
                                          parameterValueArray,
                                          SRSReportFileFormat::PDF,
                                          printSettings.deviceInfo());

System.IO.File::WriteAllBytes("c:\\temp\\test.pdf", reportBytes);

If you need a stream instead, it should be trivial to create one with the byte array using the .net framework.

Thursday, November 13, 2014

Search Available Icons From Embedded Resources

Do you also hate looking for icons in AX when creating forms, because you need to scroll through all those images every time and they haven't even got a name to filter by?

Then I've finally got a solution for you! :)

I've made a new tool which allows you to search available image resources in AX 2012. The idea is that it traverses all form nodes and menu items for elements with icons and stores the icon resource id, label and help text. This is saved in a table, so it only needs to be done once.

When presenting this on a form, you can search for images using a text query!

Searching for "Refresh"


Download XPO

Monday, October 20, 2014

Show open windows in development view and switch between them

I just developed a simple form to show all open windows i development view. It has the following features:

  • Double-click an item to switch to the corresponding window.
  • Click "Close window" to close the selected window.
  • Auto-refreshes the view every 3 seconds.
  • Stays within the workspace (i.e. not "outside AX").
  • Stays open after switching windows (unlike the default Windows -> Windows)!
  • Works in both Dynamics AX 2009 and 2012.

It has greatly helped me manage my windows when developing...! :)

When imported, you should add a menu item pointing to the form (eg. in \Menus\GlobalToolsMenu on AX 2012).


Let me know if you need more features :)

Screenshot:



Wednesday, May 7, 2014

Error executing code: object does not have method 'loadProject'.

If you get the following error when attempting to open a project in AX 2012 or AX hangs indefinitely:

Error executing code:  object does not have method 'loadProject'.
Stack trace

(C)\Classes\\loadProject

Then just run:
AxUtil schema
(or initialize-axmodelstore if you are using powershell)

If you are running your AX 2012 on SQL 2012, then you also need to apply the following hotfix:
KB2680186

I have seen this error after importing a CU7 model on RTM.

Thursday, March 27, 2014

AX 2012 SSRS - Misc Problems and Solutions

Problem
You get a http 503 service unavailable during installation of Report Extensions.

Solution
Remove Report Server settings in AX.

Problem
Can't install Report Extensions. Error message:

"An error occurred during setup of Reporting Services extensions.
Reason: Could not load file or assembly 'Microsoft.SqlServer.BatchParser, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified."

Solution
Install Microsoft® SQL Server® 2008 R2 Shared Management Objects (SMO)

You need this as well to install SMO:
Microsoft® System CLR Types for SQL Server® 2008 R2 (required package for SMO)

See: http://blogs.msdn.com/b/axsupport/archive/2012/06/26/unable-to-deploy-ax-2012-reporting-extensions-on-sql-server-2012-reporting-server.aspx

Problem
The title of the window of a SSRS report doesn't change as expected when editing it on the menu item or from Visual Studio.

Solution
Delete usage data in AX.

Problem
Error while setting server report parameters. Error message: The DefaultValue expression for the report parameter ‘AX_CompanyName’ contains an error: Request for the permission of type 'System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. (rsRuntimeErrorInExpression)

Solution
Open the file C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer\rssrvpolicy.config
Set PermissionSetName to “FullTrust” at Name=Report_Expressions_Default_Permissions

See:
http://community.dynamics.com/product/ax/axtechnical/b/axsupport/archive/2012/02/02/microsoft-dynamics-ax-2012-reporting-extensions-error-system-security-permissions-environmentpermission-while-running-report.aspx

Problem
The reports are deployed to the wrong report folder.

Solution
AX was started with the wrong active client configuration. You need to set the client configuration to the AOS that you wish to deploy to, even though you are overriding it on the client shortcut. Don't forget to restart AX afterwards - the setting is cached when AX is started.

Problem
The report cannot be deployed because it couldn't find the network path.

Solution
Start Windows service "Remote Registry"
See: http://technet.microsoft.com/en-us/library/gg724094.aspx

Problem
Error when running SSRS in batch:
"System.InvalidCastException: Unable to cast object of type 'Microsoft.Dynamics.Ax.Xpp.DictMethod' to type 'Dynamics.Ax.Application.SysDictMethod'."

Solution
Change SysDictMethod to DictMethod on line 3 in:
\Classes\SrsReportRdpRdlWrapperContractInfo\buildMemberAndNestedObjectMap

Problem
Error while setting report parameters. Error message: An error has occurred during report processing. (rsProcessingAborted)

Solution
See: https://community.dynamics.com/ax/b/axsupport/archive/2013/03/12/cannot-be-processed-at-the-receiver-due-to-a-contractfilter-mismatch-at-the-endpointdispatcher.aspx