Skip to main content

Notifications

Announcements

No record found.

Microsoft Dynamics AX (Archived)

Running Batch Job To Email Where Email is Stored Against Customer

Posted on by 280
Hi all
Running AX 2012 R3 CU9.
Our current situation is this: we have a report we email to around 20 customers every day, with sales info. For legacy reasons, we were using an Excel macro to email them out. We'd like to convert it into an SSRS batch job.
I created the report itself ages ago but we ran into a bit of an issue. Because the email targets change frequently and are out of our control, we were hoping to use the report similar to sending invoices by batch. That is, you add an email address to the customer account with a specific @tag@. You then filter the report to that one customer, and tell it to email to @tag@ and it will lookup the correct email address(es). Doing it this way would prevent us from having to modify the batch job after the fact, and pass the responsibility of keeping them up-to-date from the IT department back to the Sales department who request the changes.
Is this possible to do on a simple SSRS report that runs from a query datasource?
I was imagining I could create a small class that would do this. I have some experience with using a class which extends RunBaseBatch to create a batch job, but never one that runs an SSRS report.
Our absolute perfect scenario is having an enumerator boolean flag against CustTable which could be ticked which would indicate that this customer needs a report. The class would then look through the customer table, and run the report separately for those customers, making it one batch job rather than setting up and maintaining a growing list of them. I think if I could get the first functionality above, I could work out this bit myself.
So to reiterate, is it possible to have a RunBaseBatch-extending class run an SSRS report with a specific filter (that uses a query datasource rather than an RDP) and send it to an email address at runtime?
Thanks very much in advance for your help
Luke

*This post is locked for comments

  • lukbel Profile Picture
    lukbel 280 on at
    RE: Running Batch Job To Email Where Email is Stored Against Customer

    Hi all

    I managed to get it to work as expected

    For anyone else who needs similar solution, I had to declare Args args = new Args(); - then before running controller.startOperation() add:

    args.record(CustTable::find(_account));

    controller.parmArgs(args);

    where _account is my string variable holding my account name. Then in the other SRSController subclass created in the overridden method:

    if(this.parmArgs().record().RecId)

       {

           SrsReportHelper::addParameterValueRangeToQuery(this.getFirstQuery(),tableNum(CustTable),fieldNum(CustTable, RecId),SysQuery::value(this.parmArgs().record().RecId));

       }

    (I put the if statement in just in case it ever fell over)

    Thanks for all your help folks :) Now resolved. It only sends to internal email addresses at the moment, I found through testing. But I think this is an unrelated issue from our AX server and I will troubleshoot this separately

  • Crispin John Augustine Profile Picture
    Crispin John Augustine 37,081 on at
    RE: Running Batch Job To Email Where Email is Stored Against Customer

    From your multiple comments, it seems that you have almost figured it out.. The only pending thing is to get the customer account to pass from the form>> controller class >> report query filter.

    You have made all the right steps so far. Just place infologs on all these places and see how you can use args effectively.

    You are there.. 99.9%

  • lukbel Profile Picture
    lukbel 280 on at
    RE: Running Batch Job To Email Where Email is Stored Against Customer

    Hi all

    I've made further progress on the filtering process. By creating a class that extends SrsReportRunController and overriding method preRunModifyContract() I have been able to hardcode in a value for the report to filter in, by pointing it at that class instead of the base one. I did this by calling on the override: SrsReportHelper::addParameterValueRangeToQuery(this.getFirstQuery(),tableNum(CustTable),fieldNum(CustTable, AccountNum),SysQuery::value("C10385"));

    Now the final step is to work out how to pass in a value from the class running the report rather than hardcoding.

    I noticed that the example I saw used: "SysQuery::value(this.parmArgs().record().RecId));" And had a short explanation showing where record() is populated. (see: hellodax.com/.../modify-query-ranges-on-report-controller-class)

    However, I can't work out how args.record(TABLES_record); relates to the controller, or where you associate your Args with your controller in general based on the short snippet there.

    Any advice would be much appreciated!

    Cheers

    Luke

  • lukbel Profile Picture
    lukbel 280 on at
    RE: Running Batch Job To Email Where Email is Stored Against Customer

    Hi Crispin

    Just an update - using the documentation provided from the blog, I managed to get it to work!

    The only thing remaining is to inject my _account variable as a filter on the query. I will experiment with controller methods on the blog provided. If you have anything which will point me in the right direction pls let me know, otherwise I will keep plodding away at it :)

    Cheers

    Luke

  • lukbel Profile Picture
    lukbel 280 on at
    RE: Running Batch Job To Email Where Email is Stored Against Customer

    Hi Crispin

    Ahh I understand for number 1

    2) I can point this to the correct menuitem but it doesn't have a controller class - again, it's running using a query datasource, not an RDP class

    3) I've modified the code thus (excluding the two variable declarations at the top of the method, MenuFunction and Args, which are as before):

    args.caller();//blanked out

    args.parm(_account);

    args.parmEnumType(enumnum(boolean));

    args.parmEnum(true); // suppress report parameters dialog

    menuFunction = new MenuFunction(_menuItemStr, MenuItemType::Display);

    menuFunction.run(args);

    In this case, args.parm(_account) points to input variable on the method of type AccountNum. I would have thought you need to define the field in the actual report, or is the Extended Data Type enough to work that out?

    b) Looking at this code and it makes sense but I'm confused as to how that interfaces with menuFunction.run(args) here, as it looks like it creates its own reference to an SSRSReport.

    If I am to do one solution or the other, this second one looks more appropriate and fits my requirements almost perfectly - but I still need to pass '_account' in as a filter on that query for a filter on CustTable.AccountNum. Can you pls advise on this?

  • Verified answer
    Crispin John Augustine Profile Picture
    Crispin John Augustine 37,081 on at
    RE: Running Batch Job To Email Where Email is Stored Against Customer

    1. args.ParmEnum(true) is to stop the report Parameters Dialog from popping up. Because when it runs in batch / the Parameters are already defined by code, this window has absolutely no use (in case of batch, it shouldn't, because Dialog is a client function and it cannot work in a batch server)

    This has no Connection with Accountnum

    2. _menuItemStr is the Name of the OutPut Menuitem that references the SSRS report's Controller class.

    3. This is done in 2 steps.

    a. You already mentioned having the Customer accountNum. Pass it with the args.. args.parm(custAccountNum)

    b. For how to email the report to this custAccount's email, look at this example blogs.msdn.microsoft.com/.../how-to-directing-reports-to-email

  • lukbel Profile Picture
    lukbel 280 on at
    RE: Running Batch Job To Email Where Email is Stored Against Customer

    Hi Crispin

    Thanks for your speedy response!

    I already have a fetch for the customer number and email necessary so I'm less worried about that. I have a few questions if you have a moment to elaborate

    Looking at the example you provided:

    Args                    args = new Args();

       MenuFunction            menuFunction;

       args.caller(_caller);

       if (_buffer)

       {

           args.record(_buffer);

       }

       args.parmEnumType(enumnum(boolean));

       args.parmEnum(true); // suppress report parameters dialog

       menuFunction = new MenuFunction(_menuItemStr, MenuItemType::Output);

       menuFunction.run(args);

    1) In this instance, would I have to change args.ParmEnum(true) in order to pass the AccountNum of the current customer in as a query filter to a specific field on the report?

    2) I'm noticing _menuItemStr is passed in as a variable to this method but I can't see where it gets defined. If I hardcode this to the required report will this be ok in theory?

    3) You mentioned "parms the report print destination to email" - where exactly would I do this, looking at the example above, and is there an example of this you can point me to in the system?

    Again, thanks very much for your help, this is very enlightening

  • Suggested answer
    Crispin John Augustine Profile Picture
    Crispin John Augustine 37,081 on at
    RE: Running Batch Job To Email Where Email is Stored Against Customer

    You will Need a class (for batch processing).

    To execute an SSRS report by code, you have several standard examples.

    ProdUpd::printoutReportFromMenuItem()  is the most straight-forward one. You can then use a Controller class that fetches the email of the Customer, and parms the report print destination to Email.

    That should be it+

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Suggested Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,280 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,214 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans