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