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