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