How tos

How To pass parameters between objects (forms, reports, ...)? Revisited

Luc Van Dyck
5,61 KB
Downloaded 11 times in the last two weeks
In a previous How To, we learned about a way to pass parameters between Navision objects, by writing functions that receives the values. This How To uses a different approach.

Since MBS-Navision 3.01, codeunits can have the property SingleInstance = Yes.

The on-line help describes this SingleInstance property as follows: When you set this property to Yes on codeunit X, all codeunit variables that use codeunit X will use the same instance. That is, all codeunit variables of codeunit X will use the same set of internal variables when the code is running on the same client. Codeunit X remains instantiated until you close the company.

What this means is that the value of all variables that are used in a SingleInstance codeunit, remains in memory even after this codeunits exits. The 2nd time you use a variable from the same codeunit, it will have the previous value instead of having the default value 0 or blank.

This example uses the same 2 forms as the previous How To:

- Form1 asks for a name and two decimal values

- After clicking the "Call Form2" button, these variables are passed to a SingleInstance codeunit. Form2 retrieves the values from this codeunit, sends the result of the calculation back to the codeunit and displays the values.

- After clicking the "Return to Form1" button, focus is placed again on Form1. Form1 retrieves the result of the calculation from the codeunit and displays the value.

This is the code behind the "Call Form2" button of Form1, which passes the values to the codeunit, and retrieves the result of the calculation:

decResult := 0;
  decResult := cduPassParam.fctGetResult;

Here is the code in the OnOpenForm-trigger of Form2, which retrieves the values from the codeunit and sends back the result of the calculation:
Form - OnOpenForm()

txtName := cduPassParam.fctGetname;
decNumber1 := cduPassParam.fctGetDecimal1;
decNumber2 := cduPassParam.fctGetDecimal2;
cduPassParam.fctSetResult(decNumber1 + decNumber2);

And finally, here are the functions in the SingleInstance codeunit:
fctSetName(ptxtName : Text[30])
txtName := ptxtName;

fctSetDecimal1(pdecNumber1 : Decimal)
decNumber1 := pdecNumber1;

fctSetDecimal2(pdecNumber2 : Decimal)
decNumber2 := pdecNumber2;

fctSetResult(pdecResult : Decimal)
decResult := pdecResult;

fctGetname() : Text[30]

fctGetDecimal1() : Decimal

fctGetDecimal2() : Decimal

fctGetResult() : Decimal

The big advantage of using this method, is that you can transfer parameters without creating functions in every object.
Say you have a Form1 that calls Form2, and Form2 calls Form3. When you want to pass some value from Form1 to Form3, you needed to write a function on Form2 to retrieve the value from Form1 and you need a function on Form3 to retrieve the value from Form2. With this SingleInstance codeunit approach, Form1 sends the value to the codeunit and Form3 retrieves the value from the codeunit. There is no need to modify Form2.

Caveat: when the SingleInstance codeunit has already been executed and you modify the code inside the codeunit, you need to restart MBS-Navision. This because otherwise the version that is already in memory will be executed, instead of the new modified version.