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

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

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

Выясним причину проблемы

Разберем, почему реквизит Объект оказывается разным для разных форм одной и той же обработки:

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

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

Способ 1. Обращение к реквизитам через владельца формы

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

При открытии подчиненной формы из основной передаем ЭтаФорма в качестве параметра владельца:


// Код в основной форме
ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма.ДополнительнаяФорма", , ЭтаФорма);

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


&НаКлиенте
Процедура СохранитьИзменения()
    
    // Прямое чтение и запись реквизитов формы-владельца
    ЗначениеРеквизита = ВладелецФормы.Объект.Реквизит1;
    ВладелецФормы.Объект.Реквизит2 = НовоеЗначение;
    
КонецПроцедуры

Способ 2. Копирование данных формы (КопироватьДанныеФормы)

Если необходимо полностью скопировать структуру данных из основной формы в дополнительную перед её открытием, можно использовать функцию ПолучитьФорму и процедуру КопироватьДанныеФормы.


&НаКлиенте
Процедура ОткрытьДопФорму()
    
    ДопФорма = ПолучитьФорму("ВнешняяОбработка.МояОбработка.Форма.ДополнительнаяФорма", , ЭтаФорма);
    КопироватьДанныеФормы(Объект, ДопФорма.Объект);
    ДопФорма.Открыть();
    
КонецПроцедуры

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

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

Для передачи объемных структур данных или табличных частей наиболее надежным подходом является использование временного хранилища на сервере.

Рассмотрим алгоритм передачи по шагам:

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

Способ 4. Использование механизма оповещений и возврата выбора

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

В основной форме открываем дочернюю форму с указанием описания оповещения:


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

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

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


&НаКлиенте
Процедура ЗакрытьИСохранить()
    
    РезультатСтруктура = Новый Структура;
    РезультатСтруктура.Вставить("Реквизит1", Объект.Реквизит1);
    РезультатСтруктура.Вставить("Реквизит2", Объект.Реквизит2);
    
    ОповеститьОВыборе(РезультатСтруктура);
    
КонецПроцедуры

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

← На главную