Как передать переменную из формы обработки в общий модуль 1С 8.3

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

В процессе разработки в среде 1С:Предприятие часто возникает задача передачи специфического контекста (флагов, признаков или данных) из экранной формы в логику, описанную в общих модулях. Особенно это актуально для конфигураций на обычных формах, таких как 1С:Управление торговым предприятием (УТП). Рассмотрим, как правильно организовать передачу переменной на примере фиксации ручного ввода штрихкода.

Способ 1. Добавление параметра в процедуру общего модуля

Это самый прямой и правильный с точки зрения архитектуры способ. Если нам нужно, чтобы процедура в общем модуле «узнала» о некоем событии в форме, мы должны явно передать это событие через аргументы (параметры) функции. Проанализируем, как это реализовать по шагам.

Шаг 1. Модификация процедуры в общем модуле. Найдем нужную процедуру в общем модуле (например, ПолныеПрава) и добавим в ее заголовок новый параметр. Чтобы не нарушить работу других участков кода, где вызывается эта процедура, новому параметру следует назначить значение по умолчанию.


Процедура ВыпуститьТоварПоДокументуСТерритории(
    ДокСсылка, 
    АвтотранспортГосНомер, 
    ЧастичныйВыпуск = Ложь, 
    ТоварныйСостав = Неопределено, 
    РучнойВводКода = Ложь // Добавленный параметр с дефолтным значением
) Экспорт

    // Внутри процедуры используем переданное значение
    Если РучнойВводКода Тогда
        ДокОбъект = ДокСсылка.ПолучитьОбъект();
        ДокОбъект.РучнойВводШтрихкода = Истина;
        ДокОбъект.Записать();
    КонецЕсли;

КонецПроцедуры

Шаг 2. Вызов процедуры из формы обработки. Самая частая ошибка разработчиков заключается в том, что они присваивают значение переменной в форме, но забывают передать её в момент вызова функции. Разберем правильный вызов:


Процедура РучнойВводШтрихкодаНажатие(Элемент)
    Форма = ПолучитьФорму("ФормаРучногоВводаШтрихкода");
    Рез = Форма.ОткрытьМодально();
    
    ЛокальныйРучнойВвод = Ложь;
    Если НЕ Рез = Неопределено Тогда
        ШтрихКод = СокрЛП(Рез);
        ЛокальныйРучнойВвод = Истина; // Фиксируем факт ручного ввода
        
        // Передаем переменную в процедуру общего модуля пятым параметром
        ПолныеПрава.ВыпуститьТоварПоДокументуСТерритории(
            ВыбранныйДокумент, 
            ГосНомер, 
            Ложь, 
            Неопределено, 
            ЛокальныйРучнойВвод
        );
    КонецЕсли;
КонецПроцедуры

Способ 2. Использование структуры «ДополнительныеСвойства»

Бывают ситуации, когда процедура общего модуля имеет слишком много вызовов по всей конфигурации, и менять её заголовок (добавлять параметры) нежелательно или слишком трудозатратно. В этом случае, если процедура работает с объектом документа, мы можем использовать механизм ДополнительныеСвойства.

Проанализируем этот метод. ДополнительныеСвойства — это структура, которая существует у любого объекта (документа, справочника) и «путешествует» вместе с ним в оперативной памяти, не сохраняясь в базу данных.

Реализация в форме обработки:


// Получаем объект документа из ссылки
ДокОбъект = ДокСсылка.ПолучитьОбъект();

// Вставляем наш признак в структуру дополнительных свойств
ДокОбъект.ДополнительныеСвойства.Вставить("ФлагРучногоВвода", Истина);

// Вызываем стандартную процедуру, передавая уже объект (или ссылку, если внутри будет получение объекта)
ПолныеПрава.ВыпуститьТоварПоДокументуСТерритории(ДокОбъект, "А001АА");

Реализация в общем модуле:


Процедура ВыпуститьТоварПоДокументуСТерритории(ДокОбъект, Номер) Экспорт
    
    РучнойВвод = Ложь;
    // Проверяем, был ли передан наш флаг через дополнительные свойства
    ДокОбъект.ДополнительныеСвойства.Свойство("ФлагРучногоВвода", РучнойВвод);
    
    Если РучнойВвод Тогда
        // Выполняем логику для ручного ввода
    КонецЕсли;
    
КонецПроцедуры

Почему переменная может «не доходить» до модуля?

Разберем типичные причины, по которым значение в общем модуле остается равным Ложь, даже если в форме вы установили Истина:

  1. Область видимости: Переменная, объявленная в начале модуля формы через ключевое слово Перем, видна только внутри этой формы. Общий модуль ничего о ней не знает, пока вы не передадите её как аргумент.
  2. Пропуск параметра при вызове: Если в описании процедуры указано РучнойВводКода = Ложь, а при вызове вы написали ВыпуститьТовар(Док, Номер), 1С автоматически подставит значение Ложь. Необходимо всегда указывать позицию параметра.
  3. Разрыв контекста (Клиент-Сервер): Если вы работаете в тонком клиенте (хотя для УТП это редкость), переменные, созданные на клиенте, не переносятся на сервер автоматически. В обычных формах (толстый клиент) эта проблема встречается реже, но важно следить за тем, где именно выполняется код.

Использование универсальной структуры параметров

Профессиональным подходом считается передача не десятка отдельных переменных, а одной Структуры. Это делает ваш код масштабируемым: если завтра вам понадобится передать еще и «ID склада» или «Имя оператора», вам не придется снова менять количество аргументов в общем модуле.

Пример со структурой:


// В форме обработки
ПараметрыДействия = Новый Структура;
ПараметрыДействия.Вставить("РучнойВвод", Истина);
ПараметрыДействия.Вставить("РежимПроверки", Ложь);

ПолныеПрава.ВыпуститьТоварПоДокументу(ДокСсылка, ПараметрыДействия);

// В общем модуле
Процедура ВыпуститьТоварПоДокументу(ДокСсылка, СтруктураПараметров) Экспорт
    РучнойВвод = Ложь;
    Если ТипЗнч(СтруктураПараметров) = Тип("Структура") Тогда
        СтруктураПараметров.Свойство("РучнойВвод", РучнойВвод);
    КонецЕсли;
    // ... дальнейшая логика
КонецПроцедуры

Подведем итог: для решения задачи автора наиболее эффективным будет Способ №1 с четкой передачей параметра в вызове процедуры. Это обеспечит прозрачность кода и исключит ошибки инициализации переменных в разных контекстах.

← На главную