Как связать управляемые формы в 1С 8.3 и управлять их элементами без прямого обращения к интерфейсу

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

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

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

Архитектурная концепция: почему нельзя менять элементы «снаружи»

В управляемом приложении 1С клиентская и серверная части жестко разделены. Когда форма еще не открыта на клиенте, ее элементов физически не существует в контексте отображения. Попытка обратиться к свойству Видимость из другого программного модуля приведет либо к ошибке выполнения, либо к тому, что изменения просто проигнорируют при последующем стандартном открытии формы.

Правильный подход заключается в том, чтобы передать в подчиненную форму информацию (данные) о том, в каком состоянии она должна открыться, а сама подчиненная форма при инициализации настроит свой интерфейс самостоятельно.

Способ 1. Назначение владельца формы и использование параметров (Рекомендуемый)

Рассмотрим стандартный сценарий, когда подчиненная форма открывается из основной. Чтобы установить связь «владелец — подчиненная форма», мы передаем ссылку на основную форму в качестве параметра метода открытия.

Выясним, как это реализовать по шагам:

  1. В подчиненной форме (например, в общей форме «МойПрофиль») в ветке метаданных на вкладке Параметры создадим параметр ПользовательЗарегистрирован с типом Булево.
  2. В модуле подчиненной формы пропишем логику обработки этого параметра при создании на сервере:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Устанавливаем видимость кнопки на основании переданного параметра
    Элементы.КнопкаМойПрофиль.Видимость = Параметры.ПользовательЗарегистрирован;
КонецПроцедуры
  1. В основной форме (откуда происходит вызов) при нажатии на кнопку вызовем подчиненную форму, передав структуру параметров и указав владельца (ЭтаФорма):

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

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

Способ 2. Получение формы без немедленного открытия

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

Посмотрим на пример реализации:


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

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

Способ 3. Динамическое обновление интерфейса через Оповещения

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

Разберем этот процесс по шагам:

Шаг 1. Отправка сигнала из основной формы:

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


&НаКлиенте
Процедура ПослеУспешнойРегистрации()
    // Отправляем системное оповещение. 
    // Первый параметр - имя события, второй - дополнительные данные, третий - источник события.
    Оповестить("РегистрацияПользователяВыполнена", Ложь, ЭтаФорма);
КонецПроцедуры

Шаг 2. Прием и обработка сигнала в подчиненной форме:

В подчиненной общей форме должен быть определен предопределенный обработчик ОбработкаОповещения. Он вызывается платформой автоматически при отправке любого оповещения методом Оповестить().


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

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

Способ 4. Асинхронная работа через ОписаниеОповещения

Если подчиненная форма (например, личный кабинет) сама инициирует открытие окна регистрации и должна ожидать завершения этого процесса, то для передачи результата обратно используется современный асинхронный механизм платформы — ОписаниеОповещения.

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


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

&НаКлиенте
Процедура ПослеЗакрытияОкнаРегистрации(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
    // Сюда управление передается автоматически после закрытия формы регистрации.
    // Если регистрация прошла успешно, мы обновляем видимость кнопки на клиенте:
    Элементы.КнопкаМойПрофиль.Видимость = Истина;
КонецПроцедуры

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

← На главную