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

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

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

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

Причина возникновения дубликата формы

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


// Код в Форме1
Форма = Документы.ИмяДокумента.ПолучитьФорму("Форма2", ЭтаФорма);
Форма.НомерДокумента = ЭтотОбъект.Номер;
Форма.ДатаДокумента = ЭтотОбъект.Дата;
Форма.ОткрытьМодально();

Ошибку совершают далее, когда из Формы2 пытаются занести данные в Форму1 путем повторного поиска документа и вызова метода ПолучитьФорму():


// Ошибочный код в Форме2
Документ = Документы.ИмяДокумента.НайтиПоНомеру(НомерДокумента, ДатаДокумента);
Форма = Документ.ПолучитьФорму("ФормаДокумента", ЭтаФорма); // Платформа создает НОВЫЙ экземпляр!
Форма.СписокКонтрагентовЭкспорт = СписокКонтрагентов;
Форма.Открыть();

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

Решение: взаимодействие через владельца формы

Чтобы внести данные в уже открытое родительское окно, повторно получать форму категорически не требуется. Поскольку при открытии Формы2 в параметрах метода ПолучитьФорму() была передана ЭтаФорма в качестве владельца, дочернее окно уже содержит прямую ссылку на родительский контекст в свойстве ВладелецФормы (или Владелец).

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

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

Посмотрим на пример правильной реализации в модуле Формы1:


// Модуль Формы1
Перем СписокКонтрагентовЭкспорт Экспорт;

Процедура ДобавитьКонтрагентов() Экспорт
    Для Каждого Стр Из СписокКонтрагентовЭкспорт Цикл
        // Добавление строк в табличную часть родительской формы
        НоваяСтрока = ТабличнаяЧастьКонтрагенты.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, Стр);
    КонецЦикла;
КонецПроцедуры

Теперь рассмотрим код кнопки обработки в подчиненной форме (Форма2):


// Модуль Формы2
Процедура ПередатьДанныеВРодительскуюФорму()
    // Записываем данные непосредственно в экспортную переменную владельца
    ВладелецФормы.СписокКонтрагентовЭкспорт = СписокИндивидуальныхКонтрагентов;
    
    // Вызываем экспортный метод исходной открытой формы
    ВладелецФормы.ДобавитьКонтрагентов();
    
    // Закрываем текущую подчиненную форму
    Закрыть();
КонецПроцедуры

Альтернативные методы передачи данных

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

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

← На главную