Как оповестить форму-владельца о закрытии подчиненной формы в обычных формах 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

Способ 1. Прямой вызов экспортной процедуры формы-владельца

Разберем самый прямой и прозрачный вариант — обращение к форме-владельцу через системное свойство Владелец. В этом случае подчиненная форма напрямую вызывает процедуру, объявленную с ключевым словом Экспорт в модуле формы-владельца.

Сначала в модуле формы-владельца создадим процедуру, которая будет выполнять нужные действия при закрытии дочернего окна:


Процедура ОповеститьОЗакрытииПодчиненнойФормы() Экспорт
	// Код обновления данных или пересчета на форме-владельце
	ОбновитьТабличнуюЧасть();
КонецПроцедуры

Затем в модуле подчиненной формы перехватим событие ПриЗакрытии. Чтобы избежать ошибок выполнения (например, если подчиненная форма была открыта без указания владельца или если владелец был закрыт раньше), обязательно выполним цепочку проверок:

  1. Проверим, что свойство Владелец заполнено (Владелец <> Неопределено).
  2. Убедимся, что владельцем является именно форма, а не элемент управления (ТипЗнч(Владелец) = Тип("Форма")).
  3. Проверим, что форма-владелец все еще открыта (Владелец.Открыта()).

Посмотрим на итоговый код в модуле подчиненной формы:


Процедура ПриЗакрытии()
	Если Владелец <> Неопределено И ТипЗнч(Владелец) = Тип("Форма") Тогда
		Если Владелец.Открыта() Тогда
			Владелец.ОповеститьОЗакрытииПодчиненнойФормы();
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Способ 2. Использование глобального механизма Оповестить()

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

Главная особенность метода Оповестить() заключается в том, что оно приходит абсолютно всем открытым формам (включая саму подчиненную форму). Чтобы форма-владелец могла идентифицировать нужное событие, используем параметры метода:

В модуле подчиненной формы в обработчике события ПриЗакрытии вызовем процедуру оповещения:


Процедура ПриЗакрытии()
	Оповестить("ЗакрытаПодчиненнаяФормаВвода", СтруктураПараметров, ЭтаФорма);
КонецПроцедуры

В модуле формы-владельца опишем предопределенную процедуру ОбработкаОповещения, где отфильтруем incoming-события по имени:


Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	Если ИмяСобытия = "ЗакрытаПодчиненнаяФормаВвода" Тогда
		// Выполняем логику обновления формы-владельца
		ПрочитатьЗаполненныеДанные(Параметр);
	КонецЕсли;
КонецПроцедуры

Способ 3. Использование метода ОповеститьОВыборе()

Если подчиненная форма предназначена для выбора или подбора значений, наилучшим решением станет метод ОповеститьОВыборе(). Этот метод передает выбранное значение владельцу и автоматически закрывает подчиненную форму (если свойство ЗакрыватьПриВыборе установлено в Истина).

В модуле подчиненной формы при выборе элемента (например, по кнопке или двойному клику) вызываем:


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

На стороне формы-владельца результат выборки обрабатывается в стандартной процедуре ОбработкаВыбора:


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

Резюме

Выбор конкретного подхода зависит от архитектуры вашей задачи в 1С:

  1. Если нужно вызвать строгую логику конкретной формы-владельца — используйте прямой вызов экспортного метода через свойство Владелец с проверкой Открыта().
  2. Если событие закрытия должно обрабатываться несколькими независимыми объектами или интерфейс слабо связан — применяйте механизм Оповестить() и обработчик ОбработкаОповещения().
  3. Если задача дочернего окна заключается в подборе или выборе элемента — используйте метод ОповеститьОВыборе() и событие ОбработкаВыбора().
← На главную