Как обойти реквизиты всех открытых форм в 1С без изменения конфигурации?

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

При разработке внешних обработок часто возникает необходимость извлечь данные из уже открытых пользователем окон. Например, при обработке документов ТТН может потребоваться автоматически подтянуть ФСРАР ID и идентификатор накладной прямо из открытой формы, не заставляя пользователя вводить их вручную. Рассмотрим, возможно ли реализовать такой функционал штатно и с какими ограничениями платформы можно столкнуться.

Получение открытых форм в управляемом приложении

В управляемом интерфейсе платформа 1С предоставляет инструменты для работы с окнами клиентского приложения. Для получения списка открытых окон используется глобальный контекст ОкнаКлиентскогоПриложения и его метод ПолучитьОкна().

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

  1. Вызываем метод ПолучитьОкна() для получения массива всех окон приложения.
  2. Для каждого окна обращаемся к свойству Содержимое, которое представляет собой массив форм, находящихся в данном окне.
  3. Для каждой найденной формы получаем список её реквизитов с помощью метода ПолучитьРеквизиты().

Рассмотрим пример кода для обхода форм и их реквизитов на клиенте:


МассивОкон = ОкнаКлиентскогоПриложения.ПолучитьОкна();
Для Каждого Окно Из МассивОкон Цикл
    Для Каждого Форма Из Окно.Содержимое Цикл
        // Получаем массив объектов типа РеквизитФормы
        МассивРеквизитов = Форма.ПолучитьРеквизиты();
        Для Каждого Реквизит Из МассивРеквизитов Цикл
            ИмяРеквизита = Реквизит.Имя;
            
            // Обращение к значению реквизита через квадратные скобки
            Попытка
                Значение = Форма[ИмяРеквизита];
            Исключение
                // Если реквизит входит в состав основного объекта (например, Объект.ИмяРеквизита)
            КонецПопытки;
        КонецЦикла;
    КонецЦикла;
КонецЦикла;

Важные нюансы и ограничения в управляемых формах

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

  1. Метод ПолучитьРеквизиты() возвращает метаданные: Данный метод возвращает массив объектов типа РеквизитФормы (описание структуры: имя, тип, путь), а не сами значения. Чтобы считать значение, необходимо обращаться непосредственно к свойству формы по имени: Форма[ИмяРеквизита].
  2. Данные объекта: Если основным реквизитом формы выступает объект (например, ДокументОбъект), значения его полей хранятся внутри реквизита Объект, и обращение выполняется в формате Форма.Объект[ИмяРеквизита].
  3. Клиент-серверное разделение: На клиенте нельзя обращаться «через точку» к свойствам ссылочных типов (например, Форма.Объект.Организация.ИНН). Для извлечения данных из реквизитов-ссылок потребуется передавать их на сервер в функцию с директивой &НаСервереБезКонтекста.
  4. Основное окно и модальность: В свойстве Содержимое для главного окна приложения (где Основное = Истина) всегда находится пустой массив. Кроме того, метод ПолучитьОкна() не видит модальные окна и системные диалоги выбора файлов.

Ситуация с обычным приложением (обычные формы)

В обычном интерфейсе ситуация принципиально иная: глобальный реестр открытых экземпляров форм отсутствует. При попытке вызвать метод ПолучитьОкна() платформа возвращает значение Неопределено.

Обращение к метаданным (например, Метаданные.Документы.ИмяДокумента.Формы) даёт лишь описание структуры из конфигуратора, но не предоставляет доступа к работающим экземплярам окон. Попытка обхода через ЭлементыФормы дает доступ только к элементам управления конкретной текущей формы, но не позволяет найти другие открытые окна.

Таким образом, в обычном приложении штатно обойти открытые формы из внешней обработки без доработки конфигурации невозможно. Для реализации такого функционала пришлось бы внедрять в формы код логирования, фиксирующий открытие и закрытие окон в глобальном массиве или параметрах сеанса.

Альтернативные решения без изменения основной конфигурации

Если конфигурацию менять нельзя, но задачу решить необходимо, разберем следующие альтернативные подходы:

  1. Использование расширений конфигурации (для управляемых форм): Если основная конфигурация находится на поддержке, можно создать расширение. В нем с помощью аннотаций &После или &Вместе подцепляются события открытия форм (ПриСозданииНаСервере или ПриОткрытии) и сохраняются ссылки на нужные формы или значения их реквизитов во временное хранилище.
  2. Механизм клиентских оповещений: Внешняя обработка может вызвать команду Оповестить("ЗапросДанныхТТН", Параметры). Если в открытых формах реализован обработчик события ОбработкаОповещения, они смогут принять запрос и отправить ответ с запрашиваемыми данными (например, ФСРАР ID).
  3. Внешние компоненты Win32 API (для обычных форм): Единственный способ считать информацию об открытых окнах обычного приложения без изменения 1С — применение внешних компонентов на C++ или COM, работающих с Win32 API (функции EnumWindows, GetWindowText). Однако этот метод позволяет считать только видимый текст заголовков и полей ввода, без доступа к объектам 1С.
← На главную