В процессе разработки в среде 1С:Предприятие часто возникает задача передачи специфического контекста (флагов, признаков или данных) из экранной формы в логику, описанную в общих модулях. Особенно это актуально для конфигураций на обычных формах, таких как 1С:Управление торговым предприятием (УТП). Рассмотрим, как правильно организовать передачу переменной на примере фиксации ручного ввода штрихкода.
Это самый прямой и правильный с точки зрения архитектуры способ. Если нам нужно, чтобы процедура в общем модуле «узнала» о некоем событии в форме, мы должны явно передать это событие через аргументы (параметры) функции. Проанализируем, как это реализовать по шагам.
Шаг 1. Модификация процедуры в общем модуле. Найдем нужную процедуру в общем модуле (например, ПолныеПрава) и добавим в ее заголовок новый параметр. Чтобы не нарушить работу других участков кода, где вызывается эта процедура, новому параметру следует назначить значение по умолчанию.
Процедура ВыпуститьТоварПоДокументуСТерритории(
ДокСсылка,
АвтотранспортГосНомер,
ЧастичныйВыпуск = Ложь,
ТоварныйСостав = Неопределено,
РучнойВводКода = Ложь // Добавленный параметр с дефолтным значением
) Экспорт
// Внутри процедуры используем переданное значение
Если РучнойВводКода Тогда
ДокОбъект = ДокСсылка.ПолучитьОбъект();
ДокОбъект.РучнойВводШтрихкода = Истина;
ДокОбъект.Записать();
КонецЕсли;
КонецПроцедуры
Шаг 2. Вызов процедуры из формы обработки. Самая частая ошибка разработчиков заключается в том, что они присваивают значение переменной в форме, но забывают передать её в момент вызова функции. Разберем правильный вызов:
Процедура РучнойВводШтрихкодаНажатие(Элемент)
Форма = ПолучитьФорму("ФормаРучногоВводаШтрихкода");
Рез = Форма.ОткрытьМодально();
ЛокальныйРучнойВвод = Ложь;
Если НЕ Рез = Неопределено Тогда
ШтрихКод = СокрЛП(Рез);
ЛокальныйРучнойВвод = Истина; // Фиксируем факт ручного ввода
// Передаем переменную в процедуру общего модуля пятым параметром
ПолныеПрава.ВыпуститьТоварПоДокументуСТерритории(
ВыбранныйДокумент,
ГосНомер,
Ложь,
Неопределено,
ЛокальныйРучнойВвод
);
КонецЕсли;
КонецПроцедуры
Бывают ситуации, когда процедура общего модуля имеет слишком много вызовов по всей конфигурации, и менять её заголовок (добавлять параметры) нежелательно или слишком трудозатратно. В этом случае, если процедура работает с объектом документа, мы можем использовать механизм ДополнительныеСвойства.
Проанализируем этот метод. ДополнительныеСвойства — это структура, которая существует у любого объекта (документа, справочника) и «путешествует» вместе с ним в оперативной памяти, не сохраняясь в базу данных.
Реализация в форме обработки:
// Получаем объект документа из ссылки
ДокОбъект = ДокСсылка.ПолучитьОбъект();
// Вставляем наш признак в структуру дополнительных свойств
ДокОбъект.ДополнительныеСвойства.Вставить("ФлагРучногоВвода", Истина);
// Вызываем стандартную процедуру, передавая уже объект (или ссылку, если внутри будет получение объекта)
ПолныеПрава.ВыпуститьТоварПоДокументуСТерритории(ДокОбъект, "А001АА");
Реализация в общем модуле:
Процедура ВыпуститьТоварПоДокументуСТерритории(ДокОбъект, Номер) Экспорт
РучнойВвод = Ложь;
// Проверяем, был ли передан наш флаг через дополнительные свойства
ДокОбъект.ДополнительныеСвойства.Свойство("ФлагРучногоВвода", РучнойВвод);
Если РучнойВвод Тогда
// Выполняем логику для ручного ввода
КонецЕсли;
КонецПроцедуры
Разберем типичные причины, по которым значение в общем модуле остается равным Ложь, даже если в форме вы установили Истина:
Перем, видна только внутри этой формы. Общий модуль ничего о ней не знает, пока вы не передадите её как аргумент.РучнойВводКода = Ложь, а при вызове вы написали ВыпуститьТовар(Док, Номер), 1С автоматически подставит значение Ложь. Необходимо всегда указывать позицию параметра.Профессиональным подходом считается передача не десятка отдельных переменных, а одной Структуры. Это делает ваш код масштабируемым: если завтра вам понадобится передать еще и «ID склада» или «Имя оператора», вам не придется снова менять количество аргументов в общем модуле.
Пример со структурой:
// В форме обработки
ПараметрыДействия = Новый Структура;
ПараметрыДействия.Вставить("РучнойВвод", Истина);
ПараметрыДействия.Вставить("РежимПроверки", Ложь);
ПолныеПрава.ВыпуститьТоварПоДокументу(ДокСсылка, ПараметрыДействия);
// В общем модуле
Процедура ВыпуститьТоварПоДокументу(ДокСсылка, СтруктураПараметров) Экспорт
РучнойВвод = Ложь;
Если ТипЗнч(СтруктураПараметров) = Тип("Структура") Тогда
СтруктураПараметров.Свойство("РучнойВвод", РучнойВвод);
КонецЕсли;
// ... дальнейшая логика
КонецПроцедуры
Подведем итог: для решения задачи автора наиболее эффективным будет Способ №1 с четкой передачей параметра в вызове процедуры. Это обеспечит прозрачность кода и исключит ошибки инициализации переменных в разных контекстах.