Как отследить интерактивное открытие обработки и вызвать экспортный метод ее объекта в обычном приложении 1С 8.3?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке функционала в режиме «Обычное приложение» (толстый клиент, обычные формы) на платформе 1С:Предприятие 8.3 нередко возникает задача: пользователь интерактивно открывает определенную обработку (встроенную или внешнюю .epf), а системе требуется зафиксировать факт открытия и выполнить экспортные методы модуля объекта этого конкретного экземпляра.

Разработчики, привыкшие к управляемым формам и интерфейсу «Такси», часто пытаются использовать метод ПолучитьОкна() или объект ОкнаКлиентскогоПриложения. Однако в обычном приложении этот механизм недоступен. Разберем особенности архитектуры толстого клиента, выясним причину ограничений и детально рассмотрим надежные способы решения поставленной задачи.

Особенности архитектуры обычного приложения и доступ к объекту

Проанализируем ключевые различия между управляемым и обычным приложением в контексте работы с формами обработок:

  1. Единое адресное пространство памяти: В обычном приложении толстый клиент выполняет как код формы, так и код модуля объекта в одном процессе сеанса пользователя. Нет разделения на тонкий клиент и серверные контексты без контекста формы.
  2. Прямая связь формы и объекта: В обычной форме обработки всегда существует встроенное свойство ЭтотОбъект (а также ОбработкаОбъект), которое возвращает прямую ссылку на экземпляр ОбработкаОбъект.<Имя> или ВнешняяОбработкаОбъект.<Имя>.
  3. Отсутствие системного менеджера окон: Метод ПолучитьОкна() появился для управляемого интерфейса. В обычных формах отслеживание открытых окон реализуется либо через события форм, либо через регистрацию экземпляров в общих модулях.

Рассмотрим несколько практических вариантов реализации взаимодействия с открытой обработкой.

Вариант 1. Регистрация ссылки на открытый объект в глобальной переменной или общем модуле

Разберем по шагам самый простой и прямой способ: при интерактивном открытии обработка сама регистрирует свой экземпляр в общедоступном месте, а при закрытии — очищает ссылку.

Создадим или выберем клиентский общий модуль (например, КонтекстСеансаКлиент) с признаком Клиент (обычное приложение) и объявим в нем экспортную переменную:


// Общий модуль: КонтекстСеансаКлиент
Перем ОткрытыйЭкземплярОбработки Экспорт;

Теперь обратимся к модулю формы самой обработки. В обработчиках событий ПриОткрытии и ПриЗакрытии пропишем регистрацию объекта:


// Модуль обычной формы обработки

Процедура ПриОткрытии()
    // Сохраняем ссылку на объект обработки в глобальную переменную
    КонтекстСеансаКлиент.ОткрытыйЭкземплярОбработки = ЭтотОбъект;
    
    // Если нужно выполнить экспортный метод объекта сразу при открытии:
    ЭтотОбъект.МойЭкспортныйМетод();
КонецПроцедуры

Процедура ПриЗакрытии()
    // Очищаем ссылку при закрытии формы, чтобы избежать утечек памяти
    КонтекстСеансаКлиент.ОткрытыйЭкземплярОбработки = Неопределено;
КонецПроцедуры

Посмотрим на пример вызова экспортного метода открытой обработки из любого другого места конфигурации (из другой формы, меню или общего модуля):


// Вызов из внешнего контекста (например, по нажатию кнопки в другой форме)

Если КонтекстСеансаКлиент.ОткрытыйЭкземплярОбработки <> Неопределено Тогда
    // Объект открыт интерактивно, вызываем его метод
    КонтекстСеансаКлиент.ОткрытыйЭкземплярОбработки.МойЭкспортныйМетод();
Иначе
    Сообщить("Обработка в данный момент не открыта пользователем!");
КонецЕсли;

Вариант 2. Использование механизма глобальных оповещений (Оповестить и ОбработкаОповещения)

Рассмотрим более гибкий подход с использованием механизма слабой связанности. В этом случае внешнему коду не нужно хранить прямую ссылку на объект обработки — достаточно послать оповещение в систему.

Разберем реализацию по шагам:

  1. В модуле обычной формы обработки переопределяем процедуру ОбработкаОповещения.
  2. Из модуля формы вызываем экспортный метод модуля объекта ЭтотОбъект.ИмяМетода() при получении целевого события.
  3. Сторонний алгоритм посылает оповещение процедурой Оповестить(). Если форма открыта — метод выполнится, если закрыта — оповещение пройдет бесследно.

Посмотрим на программный код в модуле формы обработки:


// Модуль формы обработки

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    
    Если ИмяСобытия = "ВыполнитьДействиеВОткрытойОбработке" Тогда
        // Вызываем экспортную процедуру модуля объекта
        ЭтотОбъект.МойЭкспортныйМетод(Параметр);
    КонецЕсли;
    
КонецПроцедуры

В вызывающем коде отправляем команду через глобальный метод платформы 1С:


// Вызывающий модуль

ПараметрыВызова = Новый Структура;
ПараметрыВызова.Вставить("ДатаСобытия", ТекущаяДата());
ПараметрыВызова.Вставить("Пользователь", ИмяПользователя());

Оповестить("ВыполнитьДействиеВОткрытойОбработке", ПараметрыВызова, "ГлавнаяФорма");

Вариант 3. Работа с внешней обработкой (.epf) по пути к файлу

Проанализируем ситуацию, когда обработка является внешней (файл .epf), открывается пользователем через системное меню «Файл -> Открыть», и нам необходимо получить именно открытую форму или экземпляр объекта.

В обычной форме внешней обработки свойство ИспользуемоеИмяФайла содержит полный путь к файлу на диске. Рассмотрим пример сохранения информации о файле и повторного обращения к открытой форме:


// Модуль формы внешней обработки

Процедура ПриОткрытии()
    // ИспользуемоеИмяФайла содержит путь к .epf файлу
    ПутьКФайлу = ЭтотОбъект.ИспользуемоеИмяФайла;
    
    // Регистрируем открытый файл в общем соответствии открытых обработок
    КонтекстСеансаКлиент.РегистрироватьОткрытуюОбработку(ПутьКФайлу, ЭтаФорма);
КонецПроцедуры

Если нам требуется получить существующую форму внешней обработки, используем метод ВнешниеОбработки.ПолучитьФорму():


// Получение ссылки на форму уже открытой внешней обработки
ПутьКФайлу = "C:\Обработки\МояОбработка.epf";

ФормаОбработки = ВнешниеОбработки.ПолучитьФорму(ПутьКФайлу, "Форма");
Если ФормаОбработки.Открыта() Тогда
    // Доступ к объекту обработки через форму
    ОбъектОбработки = ФормаОбработки.ЭтотОбъект;
    ОбъектОбработки.МойЭкспортныйМетод();
КонецЕсли;

Сравнение и рекомендации

Подведем итоги анализа рассмотренных способов:

  1. Прямой вызов через ЭтотОбъект из ПриОткрытии: Идеально подходит, если экспортный метод должен вызываться сразу же в момент интерактивного открытия самой формы.
  2. Механизм Оповестить() / ОбработкаОповещения(): Наиболее надежный и безопасный вариант взаимодействия между несвязанными формами, исключающий появление «зависших» ссылок в оперативной памяти сеанса.
  3. Глобальная переменная или реестр открытых форм: Оптимален, если стороннему коду необходимо гарантированно знать состояние обработки (открыта/закрыта) и передавать в нее данные синхронно с получением возвращаемого значения.
← На главную