Передача параметров между управляемыми формами является одной из базовых и часто встречающихся задач при разработке в 1С:Предприятии. Правильный подход к решению этой задачи обеспечивает гибкость, надежность и поддерживаемость вашего кода. В этом материале мы подробно рассмотрим рекомендуемые методы для передачи данных от одной формы к другой, а также для получения результатов работы открытой формы обратно в вызвавшую.
Наш вопрос состоит из двух основных частей:
Прежде чем мы углубимся в детали, сразу отметим, что для таких задач категорически не рекомендуются
ПараметрыСеанса
Константы
Для передачи данных из ФормыСписка в ФормуДокумента при ее открытии мы будем использовать метод
ОткрытьФорму()
В ФормеСписка (или любой другой форме, из которой вы открываете новую форму), необходимо сформировать структуру с параметрами, которые вы хотите передать. Затем эта структура передается вторым аргументом метода
ОткрытьФорму()
Рассмотрим пример, когда нам нужно открыть форму документа и передать в неё некие
пПервыйПараметр
пВторойПараметр
// В модуле формы-списка (например, в обработчике команды)
&НаКлиенте
Процедура ОткрытьФормуДокументаСПараметрами(Команда)
// Предположим, у нас есть некоторые значения для передачи
ПередаваемыйПервыйПараметр = "Некое строковое значение";
ПередаваемыйВторойПараметр = Новый Дата(2023, 1, 1);
// Создаем структуру для передачи параметров
// Ключи структуры (строки "ПервыйПараметр", "ВторойПараметр")
// станут именами свойств в коллекции Параметры открываемой формы.
П = Новый Структура("ПервыйПараметр, ВторойПараметр", ПередаваемыйПервыйПараметр, ПередаваемыйВторойПараметр);
// Открываем форму документа, передавая ей структуру с параметрами
ОткрытьФорму("Документ.МойДокумент.Форма.ФормаДокумента", П);
КонецПроцедуры
Мы создаем
Новый Структура()
"Документ.МойДокумент.Форма.ФормаДокумента"
В открываемой ФормеДокумента (или любой другой форме, которая принимает параметры), переданные значения будут доступны через свойство формы
Параметры
ПриСозданииНаСервере
Посмотрим на пример из обсуждения, как мы можем получить эти параметры:
// В модуле формы документа
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Инициализация формы или её реквизитов на основе переданных параметров
// Проверяем, были ли переданы параметры
Если Параметры.Свойство("ПервыйПараметр") Тогда
// Сохраняем значение в реквизит формы, чтобы использовать его в других процедурах
ЭтотОбъект.ПервыйПараметрФормы = Параметры.ПервыйПараметр;
// Можем сразу использовать параметр, например, для инициализации поля
Сообщить("Получен ПервыйПараметр: " + ЭтотОбъект.ПервыйПараметрФормы);
КонецЕсли;
Если Параметры.Свойство("ВторойПараметр") Тогда
// Сохраняем значение в реквизит формы
ЭтотОбъект.ВторойПараметрФормы = Параметры.ВторойПараметр;
Сообщить("Получен ВторойПараметр: " + ЭтотОбъект.ВторойПараметрФормы);
КонецЕсли;
// ... дальнейшая логика инициализации формы ...
// Если форма открывается для нового документа,
// а нам нужно инициализировать его на основе параметров,
// то можно сделать следующее:
Если Объект.ЭтоНовый() Тогда
Если Параметры.Свойство("ТипОперации") Тогда
Объект.ТипОперации = Параметры.ТипОперации;
КонецЕсли;
// и т.д. для других реквизитов объекта документа
КонецЕсли;
КонецПроцедуры
В этом примере мы видим, как важно использовать
Параметры.Свойство("ИмяПараметра")
ЭтотОбъект.ПервыйПараметрФормы
Чтобы реквизит формы был доступен, его необходимо предварительно создать в конфигураторе для данной формы. Вы можете добавить реквизит формы с нужным типом (например, "Строка", "Дата", "СправочникСсылка.МойСправочник" и т.д.), и затем присваивать ему значения в
ПриСозданииНаСервере
ЭтотОбъект.ИмяВашегоРеквизита
Для возврата результатов работы из закрываемой ФормыДокумента обратно в вызвавшую ее ФормуСписка, наиболее правильным и асинхронным способом является использование механизма
ОписаниеОповещения
При открытии ФормыДокумента из ФормыСписка, мы передаем объект
ОписаниеОповещения
ОткрытьФорму()
Разберем пример из сообщения 3:
// В модуле формы-списка (например, в обработчике команды)
&НаКлиенте
Процедура Выгрузить(Команда)
Парам = Новый Структура;
Парам.Вставить("РежимВыбора", Истина);
// Допустим, мы хотим передать какой-то документ для выгрузки в форму выбора
// В данном примере это просто ссылка на текущий объект формы-списка
// В реальной ситуации это может быть любой другой параметр
// например, ссылка на текущий элемент списка или другой контекст.
// Для примера, возьмем текущий объект формы:
// Парам.Вставить("ДокументВыгрузки", Форма.Объект.Ссылка);
// Или, если у нас нет конкретного документа, но есть другие параметры
Парам.Вставить("НачальноеЗначение", "Значение для выбора");
// Создаем ОписаниеОповещения
// Первый параметр - имя процедуры, которая будет вызвана после закрытия формы.
// Второй параметр - контекст (обычно ЭтотОбъект для текущей формы).
// Третий параметр (опционально) - дополнительные параметры, которые будут переданы в процедуру-обработчик.
ОбработкаВыбора = Новый ОписаниеОповещения("ВыгрузкаДокументаКонец", ЭтотОбъект, Парам);
// Открываем форму, передавая в неё параметры и ОписаниеОповещения.
// Используем полные параметры метода ОткрытьФорму:
// 1. Имя формы
// 2. Параметры открываемой формы (для её инициализации)
// 3. Владелец формы (обычно ЭтотОбъект, чтобы открываемая форма знала, кто ее вызвал)
// 4. УникальныйИдентификатор (необязательно, если не нужен)
// 5. Окно (необязательно, если не нужен)
// 6. КлючУникальности (необязательно)
// 7. ОписаниеОповещения (наш объект ОбработкаВыбора)
// 8. РежимОткрытияОкнаФормы (например, блокировать весь интерфейс)
ОткрытьФорму("Справочник.МойСправочник.Форма.ФормаВыбора", Парам, ЭтотОбъект,,,, ОбработкаВыбора, РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс);
КонецПроцедуры
// Процедура-обработчик, которая будет вызвана после закрытия формы выбора
// Она должна быть Экспортной, если вызывается извне.
// Первый параметр - результат, переданный закрывающейся формой.
// Второй параметр - дополнительные параметры, которые мы передали при создании ОписаниеОповещения.
&НаКлиенте
Процедура ВыгрузкаДокументаКонец(МойЭлемент, ПараметрыВыгрузки) Экспорт
// МойЭлемент - это то, что передала закрывающаяся форма через ОповеститьОВыборе() или Закрыть().
// ПараметрыВыгрузки - это Парам, которые мы создали в процедуре Выгрузить.
Если МойЭлемент = Неопределено Тогда
Сообщить("Выбор отменен или форма закрыта без результата.");
Возврат;
КонецЕсли;
Сообщить("Выбран элемент: " + МойЭлемент + ". Режим выбора: " + ПараметрыВыгрузки.РежимВыбора);
// Здесь мы можем обновить список, выполнить какие-либо действия
// например, записать выбранный элемент в реквизит или обновить табличную часть.
// Если требуется обновить данные в списке:
// ОбновитьЭлементы();
КонецПроцедуры
В этом примере мы видим, как создается
ОписаниеОповещения
ВыгрузкаДокументаКонец
ЭтотОбъект
Парам
ОбработкаВыбора
ОткрытьФорму()
В ФормеДокумента (или любой другой форме, которую вы открыли и из которой нужно вернуть результат), когда работа завершена и результат готов, мы используем метод
ОповеститьОВыборе()
Закрыть()
Закрыть()
ОписаниеОповещения
Продолжим пример, как ФормаДокумента может вернуть значение:
// В модуле формы документа
&НаКлиенте
Процедура КомандаВыбрать(Команда)
// Предположим, мы хотим вернуть ссылку на текущий объект формы документа
// или какое-либо другое значение, сформированное в форме.
ВыбранноеЗначение = Объект.Ссылка; // Или, например: ВыбранноеЗначение = "Какой-то результат";
// Если форма была открыта с ОписаниеОповещения,
// вызов ОповеститьОВыборе() или Закрыть() передаст это значение
// в процедуру-обработчик в вызвавшей форме.
ОповеститьОВыборе(ВыбранноеЗначение);
// После оповещения можно закрыть форму.
// Если передать значение в Закрыть(), то оно будет передано в оповещение.
// Закрыть(ВыбранноеЗначение);
КонецПроцедуры
// Также, если пользователь просто закрывает форму без явного выбора,
// но вы хотите вернуть "пустой" или "отмененный" результат,
// можно обработать это в ПриЗакрытии.
&НаКлиенте
Процедура ПриЗакрытии(Отказ)
Если Не ЗначениеЗаполнено(ВыбранноеЗначение) Тогда // Предполагаем, что ВыбранноеЗначение - это реквизит формы
// Если выбор не был произведен явно, оповещаем о Неопределено
// Это полезно, чтобы вызывающая форма знала, что выбора не было.
ОповеститьОВыборе(Неопределено);
КонецЕсли;
КонецПроцедуры
После вызова
ОповеститьОВыборе(ВыбранноеЗначение)
Закрыть(ВыбранноеЗначение)
ВыгрузкаДокументаКонец
ВыбранноеЗначение
МойЭлемент
Как мы уже упоминали, использование
ПараметровСеанса
Констант
ПараметрыСеанса
Константы
Всегда отдавайте предпочтение прямым механизмам передачи параметров, таким как аргументы методов
ОткрытьФорму()
ОписаниеОповещения
Вопрос, поднятый в обсуждении, очень важен: "А если документ будет открыт не из форм списка, а из какого-нибудь реквизита или по навигационной ссылке или из избранного. Логика безопасности не нарушится?"
Мы должны всегда помнить, что форма может быть открыта не только из того места, где мы ожидаем передачу параметров. Пользователь может:
В таких сценариях параметры могут быть не переданы или переданы не в том виде, в каком мы ожидаем. Чтобы избежать ошибок и обеспечить надежную работу приложения, необходимо:
Параметры.Свойство("ИмяПараметра")
ПравоДоступа("Изменение", Метаданные.Документы.МойДокумент)
Применяя описанные подходы, мы создаем гибкие, надежные и легко поддерживаемые механизмы взаимодействия между формами в 1С:Предприятии, избегая при этом распространенных ошибок и "слома стандартной обработки", которая неизбежно приводит к проблемам в долгосрочной перспективе.