Как вызвать нажатие кнопки или процедуру одной формы из другой в 1С?

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

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

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

Способ 1. Использование глобального механизма оповещений (Оповестить и ОбработкаОповещения)

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

Разберем по шагам, как настроить этот механизм:

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

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

Способ 2. Вызов экспортной процедуры клиентского контекста формы

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

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

  1. В модуле первой формы (Форма 1) объявляем процедуру с директивой &НаКлиенте Экспорт:
    
    &НаКлиенте Экспорт
    Процедура ВыполнитьДействиеПоКнопкеЭкспорт()
        // Код, выполняемый при вызове из другой формы
        // ...
    КонецПроцедуры
    
  2. Во второй форме получаем ссылку на объект первой формы (например, если форма передана как параметр при открытии или является владельцем) и вызываем метод напрямую:
    
    &НаКлиенте
    Процедура НажатьКнопкуВДругойФорме(Команда)
        // Предположим, что ссылка на целевую форму сохранена в переменной ЦелеваяФорма
        Если ЦелеваяФорма <> Неопределено И ЦелеваяФорма.Открыта() Тогда
            ЦелеваяФорма.ВыполнитьДействиеПоКнопкеЭкспорт();
        КонецЕсли;
    КонецПроцедуры
    

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

Способ 3. Использование ОписанияОповещения при открытии формы

Если Форма 2 открывается непосредственно из Формы 1, правильнее всего передавать в метод открытия callback-процедуру через объект ОписаниеОповещения.

Посмотрим на пример организации асинхронного вызова:

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

Способ 4. Механизм выбора через ОповеститьОВыборе

Если вторая форма является формой выбора или открыта с указанием владельца, можно применить стандартный механизм платформы:

  1. Во второй форме вызываем метод платформы ОповеститьОВыборе(ЗначениеВыбора).
  2. В первой форме переопределяем стандартное событие формы ОбработкаВыбора, в котором перехватываем переданное значение и выполняем нужные действия.

Способ 5. Перенос логики в общий модуль

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

← На главную