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

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

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

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

1. Передача данных между уже открытыми формами с помощью механизма оповещений

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

Как работает механизм оповещений?

  1. В форме-источнике (Форма2): Мы вызываем процедуру Оповестить() в тот момент, когда нужно передать данные. Это может быть событие ПриИзменении какого-либо реквизита, нажатие кнопки или выбор элемента из списка.

    Процедура Оповестить() принимает три параметра:

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

    Внутри процедуры ОбработкаОповещения() мы анализируем ИмяСобытия. Если оно соответствует ожидаемому, мы извлекаем переданные данные из параметра и выполняем необходимые действия, например, устанавливаем булево значение в реквизит Формы1.

Пример реализации для нашей задачи

Рассмотрим, как это будет выглядеть на практике для Формы2 и Формы1.

Начнем с Формы2. Предположим, у нас есть поле, при изменении которого мы должны передать булево значение. Пусть это будет некий реквизит формы ВыбранноеЗначение, и в зависимости от него мы формируем булево.

Код в модуле Формы2:


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

В этом примере СписокЗначенийПриИзменении — это процедура-обработчик события ПриИзменении для элемента формы, который связан со списком или полем выбора.

Теперь перейдем к Форме1. Нам нужно добавить процедуру ОбработкаОповещения().

Код в модуле Формы1:


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

В этом примере Объект.МойРеквизитБулево — это реквизит Формы1, в который мы хотим записать полученное булево значение. Важно, чтобы этот реквизит был доступен для записи (например, был реквизитом основного объекта формы или дополнительным реквизитом формы).

Важный нюанс: Для корректной работы механизма оповещений между двумя формами, они должны быть "связаны" хотя бы косвенно. Часто это достигается тем, что одна форма является владельцем другой. Например, если Форма1 открывает Форму2, то при открытии Формы2 нужно указать Форму1 в качестве владельца.

Пример открытия Формы2 из Формы1 с указанием владельца (код в модуле Формы1):


&НаКлиенте
Процедура ОткрытьФорму2(Команда)
    // Получаем форму Формы2, указывая ЭтаФорма (т.е. Форма1) как владельца
    // Предполагаем, что Форма2 находится в 'ВнешняяОбработка.ДвеФормы.Форма.Форма2'
    Форма2Ссылка = ПолучитьФорму("ВнешняяОбработка.ДвеФормы.Форма.Форма2", , ЭтаФорма);
    
    // Открываем Форму2
    Форма2Ссылка.Открыть();
КонецПроцедуры

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

2. Передача данных в форму, которая еще не открыта

Что делать, если нам нужно передать булево значение на Форму2, которая еще не открыта, и это значение должно быть установлено при ее создании? В этом случае используются параметры формы.

Механизм передачи параметров при открытии формы

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

Пример реализации

Предположим, мы хотим открыть Форму2 из Формы1 и сразу установить на Форме2 некое булево значение.

Код в модуле Формы1 (при открытии Формы2):


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

Теперь в Форме2 нам нужно получить эти параметры.

Код в модуле Формы2 (в процедуре ПриСозданииНаСервере):


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

Таким образом, Форма2 будет инициализирована нужным булевым значением сразу при ее открытии.

3. Передача данных при использовании модальных окон

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

Как работает модальное окно?

  1. Открытие модально: Родительская форма (Форма1) открывает дочернюю (Форма2) с помощью метода ОткрытьМодально(). Выполнение кода в родительской форме приостанавливается до закрытия дочерней.
  2. Возврат значения: В дочерней форме (Форма2) после выбора значения (например, булево) это значение передается в процедуру Закрыть().
  3. Получение значения: Метод ОткрытьМодально() в родительской форме возвращает значение, переданное в Закрыть() дочерней формы.

Пример реализации

Код в модуле Формы2 (после выбора значения):


&НаКлиенте
Процедура ПриВыбореЗначенияИзСписка(Команда)
    ВыбранноеБулево = Истина; // Или Ложь, в зависимости от выбора
    
    // Закрываем форму, возвращая выбранное значение
    Закрыть(ВыбранноеБулево);
КонецПроцедуры

Код в модуле Формы1 (при открытии Формы2):


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

Этот способ идеально подходит, когда Форма2 выполняет роль диалогового окна для выбора данных.

4. Прямой доступ к реквизитам и экспортным процедурам дочерней формы

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

Как реализовать прямой доступ

  1. Получаем ссылку на форму владельца: В дочерней форме мы можем получить ссылку на форму-владельца через свойство ВладелецФормы.
  2. Обращаемся к реквизитам или экспортным процедурам: Через полученную ссылку можно напрямую устанавливать значения реквизитов формы владельца или вызывать ее экспортные клиентские процедуры.

Пример реализации (менее гибкий, но возможный)

Код в модуле Формы2:


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

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

Заключение

Мы видим, что платформа 1С:Предприятие 8.3 предоставляет несколько мощных механизмов для передачи данных между управляемыми формами. Выбор конкретного подхода зависит от контекста задачи:

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

← На главную