Monday 16 May 2011

ExtendedTypeId of Enum and EDT

Just a quick post about the error encountered.
I was asked to debug an error and it has been found that it was due to developer is trying to use the "SysDictType()" class to look for the ExtendedTypeId of an enum. The code is quite dynamic, it accept the input from another setup table, which by default, it won't know what's the field that is coming in.

On the generic code, it seems like there's an assumption all field coming in will have EDT, therefore using only the SysDictType(), hence, error. The EDT name is needed for some other purpose, so I retain it. What I added is a branch to use either SysDictType() or SysDictEnum() based on the existence of the EDT.

Eg.
dictField = new DictField(tableId, fieldId);
if(dictField.typeId())
    extendedTypeId = new sysDictType(dictField.typeId()).extendedTypeId();
else if(dictField.enumId())
    extendedTypeId = new sysDictEnum(dictField.enumId()).extendedTypeId();


Thursday 12 May 2011

Send/add batch job through code on Dynamics AX

To add job into 'Batch job' using X++ code, just skip the .prompt() method.
All you need is:
- A class that extends RunBaseBatch
- A method that add the job into batch job

Eg.

classdeclaration SendBatchJob extends RunBaseBatch
{
    ....
    ....
}

//The method that calls to add the job
static void addBatchJob()
{
    SendBatchJob    sendBatch;
    ;

    sendBatch = new SendBatchJob();
    sendBatch.sendToBatch();
}

//The method that actually add the job into 'Batch job'
void sendToBatch()
{
    this.batchInfo(); //Initialize
    batchInfo.parmBatchExecute(NoYes::Yes);
    batchInfo.doBatch();
}

Friday 6 May 2011

Running batch report in AX2009 (batch printing)

Since the change of AX2009 batch framework, printing of report through batch can be done through two methods:
- Printing from server (to printer or file)
- Printing from client (the legacy batch processing)

Prerequisites: For both of the method, there're some mandatory setup:
  1. Enable any of the AOS that you want to make it as batch AOS
    (Administration -> Setup -> Server configuration)

  2. Create batch group for printing.
    Eg. One for client printing and one for server printing.
    (Administration -> Setup -> Batch groups)

  3. Add the batch group created in #2 into the AOS enabled for batch processing (in #1)

Printing from server (print to printer)
  • Enable the 'Allow clients to connect to printers on this server' settings at Dynamics AX Server Configuration Utility under the 'Application Object Server' tab.

  • Enable the 'Connect to printers on the server' settings at Dynamics AX (client) Configuration Utility under the 'Connection' tab

  • When printing report
    > At the 'Batch' tab, check the 'Batch processing' and select the batch group created for server printing
    > Click on the "Option" and select the server printer. Server printers are prefix with 'AOS:'


Printing from server (print to file)
  • Enable the 'Allow clients to connect to printers on this server' settings at Dynamics AX Server Configuration Utility under the 'Application Object Server' tab.

    *Although you're printing to file, but you still need to enable this.

  • When printing report
    > At the 'Batch' tab, check the 'Batch processing' and select the batch group created for server printing
    > Click on the "Option" and select 'File', then ensure the file name is a UNC path (Eg.\\serverName\directory) else you'll get an error.

    *After this job is added to the batch, you can check it at 'Basic > Inquiries > Batch job'. Click on the 'View tasks', notice that the 'Run location' is "Server". If your 'Run location' is "Client", then you might have selected a client printer or your report class method 'runsImpersonated()' has been overwritten to return "false".

Printing from client (through legacy batch processing)
  • When printing report
    > At the 'Batch' tab, check the 'Batch processing' and select the batch group created for client printing
    > Click on the "Option" and select the client printer

  • Run the legacy batch processing (Basic > Periodic > Batch > Processing)

    *After this job is added to the batch, you can check it at Basic > Inquiries > Batch job. Click on the 'View tasks', look at the printing job/task, it will change from "Waiting" to "Ready", then to "Executing". Also notice that the 'Run location' is "Client". The legacy batch processing require the task to be in "Ready" status, this field cannot be changed manually, it is automatically changed if you've done step #3 in the prerequisites (it might not change immediately, give it some time then refresh it and look at the status again).


Some common errors:
  • Use of printers on the server is not allowed
     

    Resolution: Ensure
    the 'Allow clients to connect to printers on this server' settings at Dynamics AX Server Configuration Utility under the 'Application Object Server' tab is checked.

  • Target file must be in UNC format


    Resolution: Ensure when you select 'File' as the output, the 'File name' is UNC path. Eg. \\serverName\directory

  • Selected printer is not an AOS printer


    Resolution: Install the printer driver on the server.
    Sometimes there're confusion regarding AOS printer and shared printer.
    For printing to works in batch mode (running from server), the printer has to be AOS printer, which the printer is "Installed" as printer on the AOS host server, not "Connect" as shared printer.

    Eg.
    There's a print server with 5 printers shared out, the AOS "Connect" to these printers, all these printers will appear as "\\printServerName\printerName01", this will not appear as AOS printer, instead, they're client printer.

    AOS printer is prefix with "AOS: " in front of the printer name in the printer selection list at print dialog.




The old/legacy client batch report printing in AX2009 concept also applies to the class. Let's say you have some process which utilize client code (Eg. needs to read Excel file), they won't run in the new AX2009 batch framework, you can then use the legacy batch processing, ensure the 'runsImpersonated()' method is overwritten to return "false", so that it will be run from client instead of server.

*Updated on 19/06/2012: Added details for "
Selected printer is not an AOS printer"