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