Add support for batch processing in Dynamics 365 for Finance and Operations

In this article we will discuss how to enable batch processing for an existing functionality in Dynamics 365 for Finance and Operations.

Let’s say that we have developed a functionality which is executed when a user clicks the OK button on a form dialog, and now we got a requirement to add support to run the same functionality in batch. This means that we want to make our form dialog ‘batchable’, i.e. we want to add a new tab with the Running in background (i.e. Batch processing) settings.

To achieve this, you can:

  1. Use the existing form as a dialog of your new batch class.
  2. Recreate the existing form dynamically using your new batch class.
  3. Add the Batch button to your form and connect the OK button with your new batch class.

In this tutorial we will focus on the third approach where we will add a new Batch button to the existing form; when this button is clicked the built-in Batch processing dialog should be shown. This approach is used when you post and print sales and purchase orders, e.g. see the Posting invoice form.

Let’s discuss briefly the first two options and then explain the third one in more detail.

1. Use your existing form as a dialog of your batch class

First, you can redesign your form to add a new TabPage control with the Running in background (i.e. Batch processing) settings. Afterwards, you need to create a new custom batch class that inherits from the RunBaseBatch class, and implement the dialog() method (among other methods) in the following way:

You can learn about this approach in detail in this article.

2. Recreate your form dynamically using only a batch class

The second option is to re-create your form completely from scratch by building it dynamically in the overridden dialogPostInit() method of your custom batch class, which has to be created by extending the RunBaseBatch class. So, your dynamically built form and business logic (the run() method) will be written in X++ in the single custom batch class inheriting from RunBaseBatch.

But what if you want to keep your existing form as is, because there is a lot of business logic going on? Or this might be an existing built-in form in Dynamics 365 for Finance and Operations so you cannot simply recreate it. For such cases the most elegant way would be to extend this form by adding a button which will open the Batch processing dialog.

3. Add the Batch button to your form

This is the simplest method and it’s also used with the Posting invoice form that you are probably familiar to. In this article we will demonstrate step-by-step on how to do it, and also add an improvement comparing to Posting invoice.

Let’s say that we have created a custom form for emailing multiple invoices to the same customer in a single email at the end of the current billing period. Afterwards, we have also added the Batch button to the form.


On this form you will notice a disabled checkbox Batch processing, which is a flag signalizing whether the invoice emailing will be performed in batch when you click the OK button. You can turn it on or off on the Batch processing dialog that is shown when the Batch button is clicked. On this form you can schedule and set up a batch job for the invoice emailing operation.

The improvement comparing to the Posting invoice form we mentioned before is that on our form we have this Batch processing checkbox, which is telling us whether the invoice emailing operation will run in batch after pressing the OK button on the form.

Take a look at the needed steps for making a form batchable by adding the Batch button.

Custom batch class

The invoice emailing operation is done using a single manager class called DocEmailInvoicesManager. Specifically, only one method of this class is the single entry point of the whole operation:

If we had a class which is structured in a way to contain parm() methods and the run() method, we would easily transform this class to a custom batch class by extending it from RunBaseBatch directly. Then we would implement the pack() and unpack() methods (and some other methods we are going to need).

But for our scenario we will introduce a new class, which will act only as a wrapper of our existing manager class (DocEmailInvoicesManager) containing the whole business logic.

This is how it’s look like:

So, we have implemented the pack() and unpack() methods, a protected constructor to force instancing the class through the construct() static method, and the run() method, as you can see below, which is just a wrapper for the entry point method of our existing manager class (DocEmailInvoicesManager).

You can also see that we have implemented the caption() method that will provide the value for the Task description field of the scheduled batch job and also the description of the batch job itself.

When opening from the Batch job history form, the batch dialog will show a caption we have provided in the caption() method that differs from the caption (Batch processing) shown on the Batch dialog when we were scheduling the batch job from our form. Also, we will see parameters of the batch job, which we have added to the dialog form in the dialogPostInit() method.

The BatchDialog action menu item

Now when we have our custom batch class created, we will add the Batch button to our form. We will achieve this by adding a built-in BatchDialog action menu item. This menu item points to the BatchDialog class that extends the RunBase class.

We also need to override the clicked() method of the Batch button, in order to create or update with the form parameters the instance of our custom batch class (DocEmailInvoicesManagerBatch).

Note that after the Batch dialog is closed, the Batch processing checkbox on our form gets refreshed depending on the selected Batch processing option from the Batch dialog.

The new runBase() method

When a batch dialog is open from the BatchDialog class invoked by the clicked BatchDialog action menu item, i.e. the Batch button on our form, it expects for a calling form to have the runBase() method implemented. If we don’t implement that method, an error will be thrown and the Batch dialog will not be shown.

That’s why we need to add the runBase() method to our form and implement it to return an instance of our custom batch class (DocEmailInvoicesManagerBatch) which is defined as a global class variable.

The OK button on the form

Finally, we have to invoke performing in batch, in case that an end-user has clicked the Batch button and turned on the Batch processing option on the Batch dialog. We will do that when the OK button is clicked.


Download the working example >>

Leave a Reply

Your email address will not be published. Required fields are marked *


Docentric respects your privacy. Learn how your comment data is processed >>

Docentric respects your privacy. Learn how your comment data is processed >>