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