Зачастую перед разработчиками 1С встает задача взаимодействия с уже открытыми окнами в интерфейсе пользователя. Одной из самых популярных задач является желание добавить глобальную кнопку (например, в общее меню Интерфейса), которая позволила бы отправлять любые открытые печатные формы (табличные документы) по электронной почте, без необходимости вносить изменения в код формирования каждого отдельного отчета или печатной формы. В старых версиях платформы, таких как 1С 7.7, эта задача легко решалась с помощью внешней компоненты FormEx. Давайте разберем, как обстоят дела в 1С:Предприятие 8 в режиме обычного приложения и какие способы решения у нас есть.
Многие разработчики, переходя на 8-ю версию платформы, пытаются найти встроенную функцию наподобие ActiveWindow или АктивныйКонтекст(). Посмотрим, почему стандартные подходы не всегда работают:
ПолучитьОкна(). Изначально может показаться логичным вызвать его, перебрать открытые окна и проверить их через ВводДоступен(). Однако этот метод предназначен исключительно для управляемого приложения (тонкий, толстый и веб-клиент). Если мы вызовем ПолучитьОкна() в режиме «Обычное приложение», платформа всегда вернет Неопределено.ТабличныйДокумент.Показать(), платформа открывает ее в собственном независимом системном окне. Программно «достучаться» до этого открытого табличного документа из команды глобального меню встроенными средствами языка 1С практически невозможно. Контекст этого окна полностью изолирован от исполняемого кода 1С.Самым грамотным, безопасным и рекомендуемым способом решения задачи является отказ от вывода табличных документов через изолированный метод Показать(). Проанализируем архитектуру типовых конфигураций (например, УТ 10.3 или УПП 1.3).
Вместо того чтобы плодить независимые окна, печатные формы выводятся в специальную общую форму (например, ОбщаяФорма.ПечатьДокументов), на которой размещен элемент управления ПолеТабличногоДокумента.
Рассмотрим по шагам, как это реализовать:
ЭлементыФормы.ПолеТабличногоДокумента, и проблема перехвата контекста полностью исчезает. Мы четко понимаем, с какими данными работаем.Если перехват активной формы строго необходим и вариант с общей формой печати не подходит, рассмотрим метод «саморегистрации» форм. Суть заключается в том, чтобы заставить каждую форму при открытии сообщать системе о своей активности.
Разберем реализацию этого алгоритма:
Массив (например, глОткрытыеФормы).ПриОткрытии() каждой нужной формы мы добавляем ссылку на саму себя в этот массив:
Процедура ПриОткрытии()
глОткрытыеФормы.Добавить(ЭтаФорма);
КонецПроцедуры
ПриЗакрытии() обязательно удаляем форму из массива, чтобы не вызывать утечек памяти и обращений к несуществующим объектам:
Процедура ПриЗакрытии()
Индекс = глОткрытыеФормы.Найти(ЭтаФорма);
Если Индекс <> Неопределено Тогда
глОткрытыеФормы.Удалить(Индекс);
КонецЕсли;
КонецПроцедуры
глОткрытыеФормы, так как он будет содержать последнюю открытую форму.Важно: Главный минус данного подхода — необходимость вносить модификации в модули абсолютно всех форм конфигурации, контекст которых мы хотим перехватывать.
Проанализируем альтернативный путь для тех, кто не хочет менять логику конфигурации. Для 8-й версии платформы существуют внешние компоненты (аналоги FormEx) и разработки на базе 1С++ или WinAPI. Они позволяют получить хэндл (HWND) активного системного окна Windows и попытаться извлечь оттуда данные.
Однако использовать системные перехватчики в 8.x для получения программного объекта 1С крайне сложно и нестабильно. Платформа 1С 8.x отрисовывает интерфейс самостоятельно, и напрямую конвертировать системное окно Windows в объект типа ТабличныйДокумент средствами 1С нельзя. Мы настоятельно не рекомендуем этот подход для решения типовых бизнес-задач, так как он приводит к падениям платформы и проблемам при обновлениях платформы.
Мы выяснили причину, по которой перехватить активное окно в обычном приложении 1С «одной кнопкой» невозможно: платформа строго изолирует окна, выведенные методами показа. Если ваша цель — унифицированная работа со всеми печатными формами (отправка по почте, сохранение, подпись), используйте архитектурный подход с созданием единой Общей формы. Это сделает ваш код прозрачным, надежным и позволит избежать проблем с правами доступа и потерей контекста.