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