Как передавать параметры между объектами (формами, отчетами и проч.)

В одной из статей мы изучили способ передачи параметров между объектами Navision с помощью спец.функций, которые принимают значения.

В данной статье используется другой подход.

Начиная с MBS-Navision 3.01, у кодеюнита появилось новое свойство SingleInstance = Yes.

Вот что пишет про это свойство встроенная справка:

«Установка этого свойства в кодеюните X влечет за собой то, что все переменные типа кодеюнит X представляют собой один экземпляр. Т.е. все переменные типа codeunit X будут использовать одинаковый набор локальных переменных во время исполнения кода на одном клиенте. Экземпляр кодеюнита X уничтожается при закрытии фирмы».

Иными словами, значения всех локальных переменных Singleinstance-кодеюнита остаются в памяти даже после того, как происходит выход из него. В следующий раз, когда вы обратитесь к этому кодеюниту, все переменные сохранят свое последнее значение, вместо 0 или ПУСТО.

В этом примере используются те же формы, что и предыдущей статье на эту тему:

  • Форма 1 запрашивает имя и два числа.

  • После нажатия кнопки «Call Form 2», переменные передаются в SingleInstance-кодеюнит.
  • Форма 2 извлекает значения из этого кодеюнита, проводит вычисления, отсылает результат обратно в кодеюнит и отображает эти значения.

  • После нажатия клавиши «Вернуться в форму 1», снова активируется Форма 1. Форма 1 извлекает результат вычислений из кодеюнита и отражает значения на экране.

Ниже приведен код, исполняемый по нажатию кнопки «Call Form2» на форме 1, которые передает значения в кодеюнит, и возвращает результат вычислений.

OnPush()
cduPassParam.fctSetName(txtName);
cduPassParam.fctSetDecimal1(decNumber1);
cduPassParam.fctSetDecimal2(decNumber2);
decResult := 0;
IF FORM.RUNMODAL(50001) = ACTION::Close THEN
decResult := cduPassParam.fctGetResult;

Следующий код вызывается из триггера OnOpenForm формы 2, который получает значения из кодеюнита и отсылает обратно результат вычислений.

Form - OnOpenForm()

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

И, наконец, вот функции из SingleInstance-кодеюнита:

fctSetName(ptxtName : Text[30])
txtName := ptxtName;

fctSetDecimal1(pdecNumber1 : Decimal)
decNumber1 := pdecNumber1;

fctSetDecimal2(pdecNumber2 : Decimal)
decNumber2 := pdecNumber2;

fctSetResult(pdecResult : Decimal)
decResult := pdecResult;

fctGetname() : Text[30]
EXIT(txtName);

fctGetDecimal1() : Decimal
EXIT(decNumber1);

fctGetDecimal2() : Decimal
EXIT(decNumber2);

fctGetResult() : Decimal
EXIT(decResult);

Достоинство данного метода в том, что передача параметров возможна без создания функций в каждом объекте.

Например, у вас есть форма 1, которая вызывает Форму 2, а форма 2, в свою очередь, вызывает форму 3. Если вы хотите передать значение из формы 1 в форму3, вам нужно две функции – одна на форме 2, для извлечения данных из формы 1, и еще одна – в форме 3 – для получения данных из формы 2.

С SingleInstance-подходом, форма 1 отсылает значение в кодеюнит, а форма 3 получает значение из этого же кодеюнита. При этом никаких изменений в форме 2 уже не потребуется.

Дополнение: при внесении изменений в SingleInstance-кодеюнит, MBS Navision необходимо рестартовать. Пока этого не сделано, в памяти будет работать старая версия.

Статья – вольный перевод ”How to” Люка ванн Дика, оригинал находится здесь: How To pass parameters between objects (forms, reports, …)? Revisited

Автор:

В области Navision - с 2003 года. Профессиональные интересы: NAV, MS SQL, .NET, BPMN, IT-менеджмент. Предметная область: логистика, финансы, склады, 3PL.

Количество статей, опубликованных автором: 86.

Комментарии (Один комментарий)

  1. cmt

    Нужно не забывать, что если использовать данный метод для учета документов, то при ситуациях, когда учет будет не успешным, в кодеюните со свойством SingleInstance эта переменная останется в том же виде, в котором была определена перед учетом.

    например:
    singleInstCU.setNotWarnOnPost(true);
    80cu.run(salesLine_); // здесь If не уместен, так как нужны все сообщения message и error в момент учета.
    singleInstCU.setNotWarnOnPost(false);

    Если в 80cu происходит ошибка, то параметр singleInstCU.setNotWarnOnPost так и останется со значением True

Добавить комментарий