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