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