Как правильно связать две управляемые формы в 1С: передача параметров, работа с владельцем и оповещения

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

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

Почему прямое использование метода ПолучитьФорму не рекомендуется

В старых конфигурациях и привычном стиле программирования разработчики часто используют метод ПолучитьФорму для непосредственного обращения к элементам другого окна. Код выглядит следующим образом:


ОбщаяФорма = ПолучитьФорму("ОбщаяФорма.Главная");
ОбщаяФорма.Открыть();
ОбщаяФорма.Элементы.МояКнопка.Видимость = Ложь;

Давайте проанализируем, почему этот подход считается устаревшим и нежелательным с точки зрения стандартов 1С:ИТС:

  1. Лишние серверные вызовы. Метод ПолучитьФорму сначала полностью создает контекст формы на сервере, передает его на клиент, а затем метод Открыть() снова инициирует серверный вызов для отображения. Это замедляет работу интерфейса, особенно в веб-клиенте или при медленном интернет-соединении.
  2. Нарушение принципа инкапсуляции. Когда одна форма напрямую «залезает» во внутреннюю структуру другой формы и меняет видимость ее элементов, код становится хрупким. Если в будущем вы переименуете кнопку МояКнопка в подчиненной форме, конфигуратор не выдаст ошибку при проверке, но в режиме предприятия программа аварийно завершит работу при попытке обращения к несуществующему элементу.

Рассмотрим современные, безопасные и производительные альтернативы для решения этой задачи.

Решение 1. Использование механизма параметров и метода ОткрытьФорму

Самый надежный способ передать данные или изменить поведение открываемой формы — использовать структуру параметров при вызове метода ОткрытьФорму. В этом случае принимающая форма сама управляет состоянием своих элементов на сервере.

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

Шаг 1. Настройка параметров в принимающей форме.

Откройте подчиненную (принимающую) форму в конфигураторе. На вкладке «Параметры» добавьте новый параметр, например, ПоказатьКнопкуПрофиля с типом Булево.

Шаг 2. Обработка параметра при создании формы.

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


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

Шаг 3. Открытие формы с передачей параметров из вызывающей формы.

В вызывающей форме (например, форме регистрации) вместо устаревшего ПолучитьФорму используем метод ОткрытьФорму, передавая в него подготовленную структуру:


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

Этот подход гарантирует стабильность работы программы, быструю скорость открытия окон и чистоту кода.

Решение 2. Динамическое обновление через механизм глобальных оповещений

Бывают ситуации, когда обе формы уже открыты на экране пользователя. Например, у пользователя открыта главная форма (с кнопками меню) и поверх нее открывается форма регистрации. После того как пользователь успешно зарегистрировался и закрыл форму регистрации, на главной форме должна немедленно стать видимой кнопка «Мой профиль».

Для решения этой задачи идеально подходит механизм оповещений платформы 1С.

Шаг 1. Отправка оповещения из формы регистрации.

В форме регистрации (после успешного выполнения записи данных) вызываем метод Оповестить:


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

Шаг 2. Прием оповещения в главной форме.

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


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

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

Решение 3. Точечное асинхронное взаимодействие через ОписаниеОповещения

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

Давайте разберем, как связать формы через асинхронный вызов:

Шаг 1. Открытие формы с указанием обработчика закрытия.

В главной форме пишем код открытия формы регистрации:


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

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

Шаг 2. Возврат результата при закрытии подчиненной формы.

В подчиненной форме регистрации при нажатии кнопки «Записать и закрыть» мы передаем результат обратно:


&НаКлиенте
Процедура ЗаписатьИЗакрытьВыполнить()
    
    // Логика записи объекта...
    // Закрываем форму и передаем Истина в качестве результата работы
    Закрыть(Истина);
    
КонецПроцедуры

Этот подход изолирует логику работы обеих форм, исключает холостые серверные запросы и является стандартом для современной разработки 1С.

Решение 4. Безопасная работа с ВладелецФормы

Иногда подчиненная форма открывается с указанием конкретного владельца, и нам требуется программно обратиться к свойствам вызывающей формы напрямую через свойство ВладелецФормы. Однако при работе с этим свойством программисты часто допускают фатальные ошибки.

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

Посмотрим на пример безопасного обращения к владельцу формы:


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

Важное ограничение: Свойство ВладелецФормы доступно исключительно в клиентском контексте. Если вам требуется обработать данные владельца на сервере, их необходимо предварительно выгрузить и передать в параметрах при открытии, либо использовать временное хранилище.

Резюме и рекомендации

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

← На главную