The operation progress form

The form showing the progress has five important parts:
1. Caption
2. Animation
3. Operation description
4. Progress indicator
5. Time remaining calculation

Initialization

Before you can begin, you must initialize the class SysOperationProgress:

SysOperationProgress progess = new SysOperationProgress();

Alternatievly you can use on of the static new methods on the SysOperationProgress Class.

Setting the caption

The caption of the form is set before the operation is carried out. 

progress.setCaption(“My Task”);

Setting the animation

Then you set the animation. You have a wide selection of animations available, run the class Tutorial_ShowAVIFiles for previewing. You do not have to specify an animation, but it is preferred.

#AviFiles progress.setAnimation(#AviUpdate);

Setting the total number of operation steps

For the progress indicator and time remaining calculation you must set the total number of operation steps to perform. If you do not specify the total, the progress indicator and the time remaining will not be shown.
The total is often a count of the number of records, and may be time consuming for it self to figure out. A rule of thumb is not to specify the total, if the total time is comparable to the counting time.

Progress.setTotal(100);

Performing the operation

Now we are ready to perform the steps in the operation. For each step we can specify a description and a step number.

for (i = 1; i <= 100; i++) { progress.setText(strfmt(”Step %1”, i)); progress.incCount(); }

The description must be short and informative, as it might change quickly during the execution.
As an alternative to incCount() you can use setCount(int i).

During the execution the progress indicator will be updated accordingly and the estimated time remaining will be calculated and displayed.

Advanced options

Progress during a simple operation can be displayed as stated above. The progress indicator can be tailored to suit your needs, if your operation is more complex.

Having more than one progress indicator

If you have a more complex operation, you can have more than one progress indicator. All the methods described above has a default parameter indicating which progress indicator (or bar) is at hand. 

Example:

static void SysOperationProgress(Args _args) { #define.count1(10) #define.count2(5) #define.count3(200) #AviFiles SysOperationProgress progress; int i, j, k; ; progress = new SysOperationProgress(3 /* three bars */); progress.setCaption("My Task"); progress.setAnimation(#AviUpdate); progress.setTotal(#count1, 1 /* bar 1 */); progress.setTotal(#count2, 2 /* bar 2 */); progress.setTotal(#count3, 3 /* bar 3 */); for (i=0; i<#count1; i++) { progress.setText( strfmt("Bar 1 - Step %1 of %2", i, #count1), 1); progress.setCount(i, 1 /* bar 1 */); for (j=0; j<#count2; j++) { progress.setText( strfmt("Bar 2 - Step %1 of %2", j, #count2), 2); progress.setCount(j, 2 /* bar 2 */); for (k=0; k<#count3; k++) { progress.setText( strfmt("Bar 3 - Step %1 of %2", k, #count3), 3); progress.setCount(k, 3 /* bar 3 */); sleep(20); // Time consuming task } } } }

If you are starting a long running operation, that might be a part of another long running operation having it's own progress indicator, don't worry. In version 3.0 of Navision Axapta, the two progress indicators will be automatically merged into the same form, thus being rendered in exactly the same way as the example above, where you handle the plumbing.

Note
The time remaining calculation is done solely on the first bar. Hence the first bar must always show the overall progress.

User input during operation

If you need user input during an operation, you have two options regarding the progress indicator.
1. Hide. This will hide the progress form and pause the time remaining calculation. The progress indicator will reappear, when setCount, incCount or setText is called subsequently.
2. Kill. This will terminate the progress form and start the progress all over. You do not have to set caption, animation and total again. 

Update interval

Running in a 3-tier environment you must avoid that updating the display becomes a performance factor. The update interval is default 3 seconds. You can specify another update interval, if you like. You can e.g. set the update interval to zero to have immediate updates.

progress.updateInterval(myUpdateInterval);

If the actually update of the form takes longer time than 10% of the update interval, the update interval is increased by one second.

Embedding the progress indicator in your form

In version 3.0 it is possible to host the progress indicator yourself e.g. on a tabpage in your form.

To do it, you must initialize the SysOperationProgressEmbedded object before super() in the forms init method:

public void init() { progress = SysOperationProgressEmbedded::newGeneral( element.form().design().control(control::tabpage)); super(); }

The form will render a progress bar with text and remaining time calculation on your form. For a detailed example see the Tutorial_Progress form.

Leverage with the Runbase Framework

Knowing the basics of operation progress indicators we can easily adopt it to the runbase framework. Runbase is the standard framework for job execution, and hence must have a progress indicator. In the standard application most progress indicators are used from this framework by far.

Initialization

Use the method progressInit to initialize the progress indicator:

public void progressInit( str caption, int total, Filename animation, int updateInterval = 1, int numOfBars = 1 )

Performing the operation

Indication progress during the actual operation is similar to the standard progress framework. Just use the member variable progress.

Progress.incCount();

Advanced options

You have exactly the same possibilities in the runbase framework, as you have with the progress indicator in general. They are all outlined above.

More Examples

See the form: Tutorial_Progress. It has about 15 different usages of the progress indicator framework.

Conclusion

Use the progress indicator to ensure that functionality is allowed to run uninterrupted. Not informing the user about a lengthy operation and its progress is likely to make him terminate the job out of sheer impatience.

Also, split up an operation in as many steps as possible. This will give the user the best information and the best remaining time estimate. You do not have to worry about the time spent informing the user since the form only is updated once a second and even less frequently on low bandwidth connections.