Как передавать параметры между объектами (формами, отчетами и проч.)
В одной из статей мы изучили способ передачи параметров между объектами 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, которые передает значения в кодеюнит, и возвращает результат вычислений.
cduPassParam.fctSetName(txtName);
cduPassParam.fctSetDecimal1(decNumber1);
cduPassParam.fctSetDecimal2(decNumber2);
decResult := 0;
IF FORM.RUNMODAL(50001) = ACTION::Close THEN
decResult := cduPassParam.fctGetResult;
Следующий код вызывается из триггера OnOpenForm формы 2, который получает значения из кодеюнита и отсылает обратно результат вычислений.
txtName := cduPassParam.fctGetname;
decNumber1 := cduPassParam.fctGetDecimal1;
decNumber2 := cduPassParam.fctGetDecimal2;
cduPassParam.fctSetResult(decNumber1 + decNumber2);
И, наконец, вот функции из SingleInstance-кодеюнита:
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.
Нужно не забывать, что если использовать данный метод для учета документов, то при ситуациях, когда учет будет не успешным, в кодеюните со свойством SingleInstance эта переменная останется в том же виде, в котором была определена перед учетом.
например:
singleInstCU.setNotWarnOnPost(true);
80cu.run(salesLine_); // здесь If не уместен, так как нужны все сообщения message и error в момент учета.
singleInstCU.setNotWarnOnPost(false);
Если в 80cu происходит ошибка, то параметр singleInstCU.setNotWarnOnPost так и останется со значением True