Можно ли программно объединить две управляемые формы в 1С?

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

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

Руками, в режиме "Такси" или при использовании интерфейса с закладками, пользователь может перетащить заголовок окна и закрепить его рядом с другим. Но как реализовать это поведение программно, чтобы при нажатии одной кнопки открывалась готовая рабочая область? Разберем этот вопрос подробно, проанализируем возможности платформы и рассмотрим существующие обходные пути.

Ограничения штатного функционала платформы

Прежде всего, давайте выясним, предоставляет ли платформа 1С встроенные механизмы для такой операции. При работе с управляемыми формами мы оперируем объектом ОкноКлиентскогоПриложения. Однако, если мы проанализируем синтаксис-помощник и доступные методы управления окнами, мы увидим, что методов для программного "докинга" (docking) или объединения двух независимых окон в одну группу (Split View) не существует.

На текущий момент платформа не позволяет программно инициировать режим разделения экрана, который доступен пользователю вручную. Это означает, что "честного" и надежного способа сказать системе "Открой Форму А и приклей к ней справа Форму Б" нет.

Решение через эмуляцию действий пользователя (WScript)

Поскольку штатного метода нет, разработчики прибегают к использованию внешних COM-объектов операционной системы Windows для эмуляции нажатия клавиш. Идея заключается в том, чтобы программно нажать комбинацию клавиш, которая в операционной системе или в интерфейсе платформы отвечает за перемещение и закрепление окна.

Рассмотрим пример кода, предложенный в профессиональном сообществе. Данный подход использует объект WScript.Shell и метод SendKeys.

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

Рассмотрим процедуру инициализации:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    
   // Запускаем таймер, чтобы выполнить действие после полной отрисовки окна
   // Например, закрепить форму сверху через 0.1 секунды
   ПодключитьОбработчикОжидания("ЗакрепитьСверху", 0.1, Истина);
   
   // Либо можно попробовать закрепить справа:
   // ПодключитьОбработчикОжидания("ЗакрепитьСправа", 0.1, Истина);

КонецПроцедуры

Теперь разберем саму логику закрепления. Скрипт эмулирует нажатия клавиш навигации и Alt (обозначен как "%"). Логика перемещения зависит от того, как именно интерфейс платформы реагирует на горячие клавиши управления окнами.

Пример 1: Закрепление формы сверху


&НаКлиенте
Процедура ЗакрепитьСверху()
    // Проверяем, доступна ли форма для ввода, чтобы не слать нажатия "в пустоту"
    Если ЭтаФорма.ВводДоступен() Тогда
        
        WSHShell = Новый COMОбъект("WScript.Shell");
        
        // Эмуляция нажатия Alt для активации меню или системных команд
        WSHShell.SendKeys("%"); 
        
        // Навигация по меню или перемещение окна стрелками
        WSHShell.SendKeys("{RIGHT 12}"); // 12 раз вправо
        WSHShell.SendKeys("{DOWN 5}");   // 5 раз вниз
        WSHShell.SendKeys("{ENTER}");    // Подтверждение
        
        // Отключаем обработчик, так как действие нужно выполнить один раз
        ОтключитьОбработчикОжидания("ЗакрепитьСверху");
    КонецЕсли;
КонецПроцедуры

Пример 2: Закрепление формы справа


&НаКлиенте
Процедура ЗакрепитьСправа()
    Если ЭтаФорма.ВводДоступен() Тогда
        WSHShell = Новый COMОбъект("WScript.Shell");
        
        WSHShell.SendKeys("%");
        WSHShell.SendKeys("{DOWN 5}");
        WSHShell.SendKeys("{RIGHT}");
        WSHShell.SendKeys("{UP 5}");
        WSHShell.SendKeys("{ENTER}");
        
        ОтключитьОбработчикОжидания("ЗакрепитьСправа");
    КонецЕсли;
КонецПроцедуры

Анализ надежности метода WScript

Хотя приведенный выше код может работать в конкретной среде разработки, давайте обсудим его недостатки. Использование SendKeys считается ненадежным методом ("костылем") по следующим причинам:

  1. Зависимость от фокуса: Если в момент срабатывания таймера (через 0.1 сек) пользователь переключится на другую программу (например, браузер), нажатия клавиш будут отправлены туда, что может привести к непредсказуемым последствиям.
  2. Зависимость от языка и версии ОС: Комбинации клавиш для управления окнами могут отличаться в разных версиях Windows и настройках платформы 1С (меню может меняться).
  3. Безопасность: В некоторых корпоративных сетях создание COM-объекта WScript.Shell запрещено политиками безопасности.
  4. Веб-клиент: Данный код не будет работать в веб-клиенте (браузере), так как там нет доступа к COM-объектам и прямому управлению окнами ОС.

Альтернативный подход: Архитектурное решение

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

Если вам необходимо показать пользователю две области данных одновременно, правильнее не открывать два окна, а создать одну общую форму. В этой форме можно использовать механизм группировок.

Рассмотрим алгоритм действий для создания надежного интерфейса:

  1. Создайте одну общую форму.
  2. В дереве элементов формы создайте Группа с видом Обычная группа.
  3. Установите для этой группы свойство Группировка в значение Горизонтальная (если нужно расположить элементы рядом) или Вертикальная (друг под другом).
  4. Поместите содержимое первой "формы" в левую часть группы, а второй — в правую.

Если данные динамические, вы можете программно управлять видимостью этих групп. Такой подход гарантирует:

Итог

На сегодняшний день прямого программного метода для объединения (докинга) двух открытых окон в 1С не существует. Решение с использованием WScript.Shell возможно, но является нестабильным и зависит от окружения. Рекомендуемым способом является проектирование интерфейса через одну форму с использованием групп для разделения рабочего пространства.

← На главную