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

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

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

Выбор конкретного метода зависит от архитектуры вашего решения, объема передаваемых данных и того, открывается ли новая форма или взаимодействие происходит между уже запущенными формами.

---

Способ 1. Передача данных через параметры формы (Рекомендуемый стандарт)

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

Давайте пошагово разберем, как реализовать этот механизм:

Шаг 1. Подготовка и отправка данных из Формы 1 (вызывающая форма)

В клиентской процедуре вызывающей формы мы формируем структуру параметров. Ключи структуры должны соответствовать именам параметров, которые мы хотим прочитать в принимающей форме.


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

Шаг 2. Прием данных в Форме 2 (принимающая форма)

В принимающей форме обработка переданных данных происходит на сервере в момент инициализации формы — в процедуре ПриСозданииНаСервере. Доступ к переданным значениям осуществляется через коллекцию Параметры.


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

Полезный совет: Для того чтобы платформа знала о существовании этих параметров, рекомендуется объявить их на вкладке «Параметры» в редакторе принимающей управляемой формы. Это упростит чтение кода другими разработчиками.

---

Способ 2. Получение данных через Владельца формы (ВладелецФормы)

Если Форма 2 открывается из Формы 1 и при этом Форма 1 явно указывается в качестве ее владельца, то в коде Формы 2 мы можем напрямую обратиться к реквизитам Формы 1 через свойство ВладелецФормы на клиенте.

Проанализируем этот способ на примере:

Шаг 1. Открытие формы с указанием владельца

При вызове метода открытия формы мы передаем ключевое слово ЭтаФорма в качестве третьего параметра (владельца формы).


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

Шаг 2. Чтение данных из владельца в Форме 2

Этот метод работает исключительно в клиентском контексте Формы 2:


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

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

---

Способ 3. Передача больших объемов данных через Временное хранилище

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

Выясним, как правильно решить эту задачу с помощью Временного хранилища:

Шаг 1. Помещение данных в хранилище в Форме 1

На сервере Формы 1 мы помещаем данные во временное хранилище, привязанное к уникальному идентификатору текущей формы, и получаем адрес ссылки.


&НаСервере
Функция ПоместитьТаблицуВХранилище()
    
    // Создаем условную таблицу данных
    ТаблицаДанных = Новый ТаблицаЗначений;
    ТаблицаДанных.Колонки.Добавить("Товар");
    ТаблицаДанных.Колонки.Добавить("Количество");
    
    // Заполняем данными...
    НоваяСтрока = ТаблицаДанных.Добавить();
    НоваяСтрока.Товар = Справочники.Номенклатура.НайтиПоКоду("00000001");
    НоваяСтрока.Количество = 10;
    
    // Помещаем во временное хранилище
    Возврат ПоместитьВоВременноеХранилище(ТаблицаДанных, УникальныйИдентификатор);
    
КонецФункции

&НаКлиенте
Процедура ПередатьТаблицу(Команда)
    
    АдресДанных = ПоместитьТаблицуВХранилище();
    
    ПараметрыПередачи = Новый Структура;
    ПараметрыПередачи.Вставить("АдресВременногоХранилища", АдресДанных);
    
    ОткрытьФорму("ОбщаяФорма.ФормаПриемникТаблицы", ПараметрыПередачи);
    
КонецПроцедуры

Шаг 2. Получение данных из хранилища в Форме 2

В Форме 2 мы считываем адрес из параметров и восстанавливаем исходный объект на сервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Параметры.Свойство("АдресВременногоХранилища") Тогда
        // Получаем объект из временного хранилища по переданному адресу
        ПолученнаяТаблица = ПолучитьИзВременногоХранилища(Параметры.АдресВременногоХранилища);
        
        // Обрабатываем таблицу значений на сервере
        Для Каждого СтрокаТаблицы Из ПолученнаяТаблица Цикл
            // Логика обработки данных...
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

---

Способ 4. Возврат данных из дочерней формы через ОписаниеОповещения (Асинхронный выбор)

Если Форма 2 открывается для того, чтобы пользователь выбрал или ввел значение, а затем передал его обратно в Форму 1, современным стандартом разработки в 1С является использование механизма обратного вызова (Callback) через ОписаниеОповещения.

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

Шаг 1. Настройка вызывающей формы (Форма 1)

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


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

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

Шаг 2. Возврат результата из Формы 2 при ее закрытии

В Форме 2 при нажатии кнопки выбора (например, кнопки «ОК») мы закрываем форму и передаем выбранное значение в качестве параметра метода Закрыть().


&НаКлиенте
Процедура КнопкаВыбратьВыполнить(Команда)
    
    ЗначениеДляПередачи = Объект.РеквизитКоторыйВыбрали;
    
    // Закрываем форму и возвращаем результат
    Закрыть(ЗначениеДляПередачи);
    
КонецПроцедуры

---

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

Когда обе формы уже открыты на экране пользователя одновременно (например, в разных вкладках интерфейса «Такси»), и при изменении реквизита в одной форме необходимо мгновенно обновить данные в другой, применяется механизм глобальных клиентских оповещений.

Проанализируем пример взаимодействия:

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

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


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

Шаг 2. Обработка оповещения в Форме 2

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


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

---

Подведем итоги. Мы рассмотрели 5 ключевых способов обмена данными между управляемыми формами в платформе 1С. Каждый из них предназначен для своего сценария:

  1. Для классического открытия новой формы используйте Параметры формы.
  2. Для быстрого считывания данных родительской формы «на лету» подойдет ВладелецФормы.
  3. При передаче таблиц, списков и файлов применяйте Временное хранилище.
  4. Для возврата результатов выбора используйте асинхронное ОписаниеОповещения.
  5. Для связывания параллельно открытых форм отлично подходят Глобальные оповещения.
← На главную