Как открыть дополнительную форму документа и связать её с данными основного объекта?

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

В процессе разработки конфигураций на платформе 1С:Предприятие 8.3 часто возникает необходимость разгрузить интерфейс основной формы документа. Мы можем захотеть вынести редко используемые реквизиты или специфические настройки (например, сложное ценообразование, детальные комментарии или параметры логистики) в отдельное диалоговое окно. Однако стандартный вызов ОткрытьФорму часто приводит к тому, что новая форма открывается пустой, так как она не "знает", с каким именно объектом ей нужно работать. Рассмотрим подробно, как правильно реализовать эту связь. Для быстрого диалогового редактирования параметров без создания отдельной формы объекта можно использовать универсальную форму ввода нескольких значений и заполнения структур.

Способ 1. Передача ключа ссылки (для записанных документов)

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

Проанализируем программный код вызова дополнительной формы из контекста основной:


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

В этом примере мы создаем структуру параметров и передаем её в функцию ОткрытьФорму. Третьим параметром мы указываем ЭтаФорма (владелец), что позволяет платформе логически связать два окна.

Способ 2. Работа с незаписанными данными через временное хранилище

Часто возникает вопрос: а как быть, если пользователь еще не нажал кнопку "Записать", но уже хочет открыть дополнительное окно и заполнить там часть данных? Передача ссылки (ключа) здесь не поможет, так как в базе данных актуальных изменений еще нет. В такой ситуации мы воспользуемся механизмом временного хранилища.

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

  1. На сервере преобразуем ДанныеФормыСтруктура (наш объект на форме) в прикладной объект ДокументОбъект.
  2. Помещаем этот объект во временное хранилище и получаем адрес.
  3. Передаем этот адрес в параметрах открытия формы.
  4. В дополнительной форме в обработчике ПриСозданииНаСервере извлекаем данные.

Пример реализации на стороне основной формы:


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

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

Важное замечание: У расширения формы документа есть стандартный параметр АдресВХранилище. Если его использовать, платформа сама попытается загрузить данные из хранилища в объект новой формы при открытии. Это избавляет нас от написания лишнего кода внутри самой дополнительной формы.

Способ 3. Использование метода КопироватьДанныеФормы

Если обе формы (основная и дополнительная) используют один и тот же тип основного реквизита (ДанныеФормыСтруктура для одного документа), мы можем применить метод КопироватьДанныеФормы. Это наиболее быстрый способ синхронизации "на лету".

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

В дополнительной форме в процедуре ПриСозданииНаСервере это выглядит так:


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

Способ 4. Возврат измененных данных и обновление основной формы

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

Разберем пример реализации в основной форме:


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

&НаКлиенте
Процедура ПослеЗакрытияДопФормы(Результат, ДополнительныеПараметры) Экспорт
    // Если данные в доп. форме сохранялись в БД, просто перечитываем объект
    ЭтаФорма.Прочитать();
    // Если же работали без записи - можно использовать Оповестить() или КопироватьДанныеФормы обратно
КонецПроцедуры

Рекомендации по оптимизации

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

Таким образом, выбор метода зависит от вашей задачи: если документ уже записан — используйте Ключ, если нет — АдресВХранилище или КопироватьДанныеФормы. Сочетание этих подходов позволит вам создавать гибкие и удобные интерфейсы для пользователей. В качестве альтернативного варианта организации интерфейса можно использовать способ встраивания одной формы внутрь другой.

← На главную