В практике разработчика 1С часто возникает задача взаимодействия между различными формами. Типичный сценарий: в обработке пользователь выбирает определенные настройки (например, номер порта для подключения весов), а затем открывает документ, в который эти настройки должны быть переданы для выполнения дальнейших операций (получение веса). В обычных формах (на примере конфигурации УПП) этот процесс имеет свои архитектурные особенности, отличные от управляемого приложения.
Разберем подробно несколько проверенных способов решения этой задачи, проанализируем их плюсы и минусы, а также выясним, как правильно организовать работу с торговым оборудованием в контексте передачи параметров.
Это самый простой и интуитивно понятный метод, характерный именно для «толстого клиента» и обычных форм. Мы можем объявить переменную в форме документа как публичную, что позволит нам записывать в нее данные непосредственно перед открытием формы.
Рассмотрим по шагам, что нужно сделать:
Экспорт.
Перем НомерПорта Экспорт;
// Получаем объект документа (если он уже существует) или создаем новый
ДокОбъект = ВыбраннаяСсылка.ПолучитьОбъект();
// Получаем форму документа
ФормаДокумента = ДокОбъект.ПолучитьФорму("ФормаДокумента");
// Передаем значение в экспортную переменную формы
ФормаДокумента.НомерПорта = НашНомерПортаИзОбработки;
// Теперь можно открывать форму
ФормаДокумента.Открыть();
Преимущество: Высокая скорость реализации и простота отладки. Мы сразу видим, какое значение передается.
Нюанс: Значение будет доступно в обработчиках ПриОткрытии или ПередОткрытием формы документа, где вы сможете использовать его для инициализации драйвера весов.
Хотя в обычных формах механизм параметров реализован не так явно, как в управляемых (через Параметры), мы все равно можем использовать расширение формы для передачи данных. Рассмотрим ситуацию, когда мы открываем форму через глобальный метод ОткрытьФорму.
Проанализируем пример кода в обработке:
ПараметрыПередачи = Новый Структура;
ПараметрыПередачи.Вставить("НомерПорта", Объект.НомерПорта);
ПараметрыПередачи.Вставить("АвтоматическоеВзвешивание", Истина);
// Открываем форму, передавая структуру в качестве параметра
ОткрытьФорму("Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента", ПараметрыПередачи);
В форме документа в процедуре ПриОткрытии мы можем проверить наличие этих параметров. Однако стоит помнить, что в обычных формах параметры часто передаются как «Владелец» или «Ключ», поэтому прямой доступ к структуре может потребовать дополнительной проверки через свойство ЭтаФорма.Параметры (зависит от конкретной версии платформы 8.3).
Если форма документа логически является подчиненной по отношению к обработке (например, обработка — это рабочее место весовщика), мы можем назначить форму обработки владельцем формы документа. Выясним, как это помогает передавать данные.
При открытии формы документа в обработке указываем владельца:
ФормаДокумента = ДокОбъект.ПолучитьФорму("ФормаДокумента", ЭтаФорма);
ФормаДокумента.Открыть();
Теперь в модуле формы документа мы всегда можем обратиться к реквизитам обработки через свойство ВладелецФормы:
Процедура ПриОткрытии()
Если ТипЗнч(ВладелецФормы) = Тип("Форма") Тогда
// Пытаемся получить реквизит "НомерПорта" из формы обработки
Попытка
ТекНомерПорта = ВладелецФормы.НомерПорта;
Сообщить("Порт весов получен от владельца: " + ТекНомерПорта);
Исключение
// Обработка ситуации, если у владельца нет такого реквизита
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Если форма документа уже открыта, и пользователь в обработке меняет номер порта, который должен мгновенно «подцепиться» документом, нам поможет метод Оповестить. Это наиболее гибкий способ взаимодействия «на лету».
В обработке при изменении номера порта вызываем:
Оповестить("ИзменениеНастроекОборудования", НомерПорта, ЭтаФорма);
В форме документа необходимо создать обработчик события ОбработкаОповещения:
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ИзменениеНастроекОборудования" Тогда
ЭтотОбъект.ТекущийПортВесов = Параметр;
// Здесь можно инициировать переподключение к весам
ОбновитьПодключениеКВесам();
КонецЕсли;
КонецПроцедуры
Важно: Этот метод работает глобально в рамках сеанса. Все открытые формы, имеющие обработчик ОбработкаОповещения, «услышат» это сообщение.
Как упоминалось в обсуждении на форуме, можно использовать ПоместитьВоВременноеХранилище. Хотя для одного числа (номера порта) это может показаться избыточным, рассмотрим этот метод для случаев, когда нужно передать сложную структуру данных.
В обработке:
АдресХранилища = ПоместитьВоВременноеХранилище(НастройкиВесов, Новый УникальныйИдентификатор());
ФормаДокумента = ДокОбъект.ПолучитьФорму("ФормаДокумента");
// Передаем только адрес (строку)
ФормаДокумента.АдресПараметров = АдресХранилища;
ФормаДокумента.Открыть();
В документе:
Если ЭтоАдресВременногоХранилища(АдресПараметров) Тогда
Настройки = ПолучитьИзВременногоХранилища(АдресПараметров);
КонецЕсли;
Поскольку конечная цель передачи номера порта — работа с оборудованием, проанализируем важный технический момент. В обычных формах работа с драйвером часто строится через ActiveX или COM-объекты. Передав номер порта, убедитесь, что:
ПриОткрытии (чтобы не тормозить интерфейс), а в обработчике Ожидание или при первом нажатии кнопки «Взвесить».Disconnect или аналогичный, иначе порт останется занятым, и повторное открытие документа (или обращение из обработки) вызовет ошибку доступа к COM-порту.НомерПорта является числом или строкой нужного формата, чтобы избежать падения системы при попытке инициализации драйвера.Подводя итог, для обычных форм УПП наиболее надежным и простым методом остается использование экспортной переменной формы. Это требует минимального количества кода и полностью соответствует архитектуре «толстого клиента».