Первая часть проблемы в том, что сам Объект (ДокументОбъект, СправочникОбъект, ОбработкаОбъект) живет на сервере, а на клиент передается только его копия с воссозданной структурой. Поэтому периодически приходится прибегать к методам вроде "РеквизитФормыВЗначение". В случае с основной формой объекта проблем почти нет. Реквизиты формы заполняются, реквизиты объекта тоже.
Но вторая часть проблемы наступает тогда, когда нам нужно вывести дополнительную форму и часть реквизитов заполнить в ней. Тогда выясняется, что реквизиты на дополнительной форме не заполняются и обратно тоже не передаются. Хотя форма не произвольная, а принадлежит обработке, и реквизит Объект – основной, и структура объекта на ней тоже воссоздается. Но данных почему-то нет... Для тех, кто с управляемыми формами работает не очень долго или не очень плотно, это становится проблемой, как я выяснил, начитавшись форумов с подобными запросами. А вся соль в том, что у этой дополнительной формы реквизит Объект – свой. И он не имеет отношения к Объекту основной формы. Воссоздается только структура объекта, без данных. Такова суровая реальность тонкого клиента )))
Вот и я не так давно столкнулся с этой проблемой и потратил пару часов на "курение" различных форумов. Мне нужно было сделать внешнюю обработку, у которой есть несколько дополнительных форм, в которых вводятся дополнительные данные, в том числе табличные. В этом случае все реквизиты должны храниться в реквизитах и табличных частях обработки и выводиться фрагментарно на различных формах. Этакая замкнутая мини-система. Данные из обработки потом сохраняются во внешнюю БД, но это уже отдельная история.
В основном на что я наткнулся при поисках, это просьба о помощи и куча стёба без дельных предложений.
Несколько решений, правда, предложено было, но все они выглядели достаточно громоздко. В основном это либо метод ПолучитьФорму(), потом заполнение реквизитов полученной формы и ее модальное открытие, а затем выполнение операций после ее закрытия. Но в случае отказа от модальности 1С постоянно на это ругается. Другой вариант – создание структуры, занесение в нее значений всех необходимых реквизитов из основной формы, а потом передача этой структуры в качестве входящего параметра при открытии дополнительной формы. А при закрытии дополнительной формы нужно снова создать структуру и передать ее обратно в основную форму. При этом в обеих формах нужно прописать чтение этих параметров и заполнение реквизитов у получателя. На одном из форумов, где предлагали подобный метод, кто-то справедливо возразил, что при передаче сотни реквизитов и десятка таблиц это становится проблемой. В итоге все чувствуют, что решение должно быть проще, но никто его так и не озвучил. Так много лишнего кода мне прописывать очень не хотелось, поэтому я продолжил копать в поисках идеального решения. Пара высказанных мыслей подсказали мне в каком направлении копать, и... Решение оказалось простым, как всё гениальное!
Итак.
Поскольку структура объектов в обеих формах у нас идентична, различается только перечень реквизитов, которые видны на форме, ничто не мешает нам передать целиком весь Объект и заполнить его копию, а потом просто вернуть его обратно. Главное – правильно это сделать.
Допустим, нам нужно по кнопке открыть дополнительную форму с парой реквизитов и табличной частью обработки, заполнить ее, а потом вернуть назад, при этом таблица на основной форме не отображается.
На стороне основной формы мы пишем:
&НаКлиенте
Процедура ОткрытиеСправочника(Команда)
ОповещениеОВыборе = Новый ОписаниеОповещения("ОткрытиеСправочникаПослеВыбора", ЭтаФорма, Новый Структура("ИмяКоманды", Команда.Имя));
ОткрытьФорму("ПолноеИмяФормы",, ЭтаФорма,,,, ОповещениеОВыборе, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
На стороне дополнительной формы мы пишем так:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
КопироватьДанныеФормы(ВладелецФормы.Объект, Объект);
КонецПроцедуры
После этого дополнительная форма будет заполнена. Затем мы делаем необходимые махинации с реквизитами и таблицами и хотим передать результат обратно. для этого мы прописываем событие у дополнительной формы:
&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Закрыть(Объект);
КонецПроцедуры
И, соответственно, снова на стороне основной формы нам нужно принять результат:
&НаКлиенте
Процедура ОткрытиеСправочникаПослеВыбора(РезультатВыбора, ДопПараметры) Экспорт
КопироватьДанныеФормы(РезультатВыбора, Объект);
// все данные объекта заполнились
Если ДопПараметры.ИмяКоманды = "ТутБылоПереданоИмяКоманды" Тогда
// выполняем дополнительные процедуры, если они нужны
КонецЕсли;
КонецПроцедуры
Возможно, для кого-то это решение покажется очевидным и он давно именно так и делает, но мне раньше подобного делать не приходилось, а при чтении форумов я подобного решения не нашел. Надеюсь, кому-то мое изыскание пригодится.
Кстати, с полным именем формы тоже могут возникнуть некоторые неудобства, ведь полное имя задается как "ВнешняяОбработка.ИмяОбработки.Форма.ИмяФормы". И если обработку переименовать, то вызов доп. форм тоже придется исправить. Одно, что у нас в таком случае не меняется - это свойство ИмяФормы. Таким образом, получив полное имя основной и подменив последний фрагмент на имя доп. формы, мы получим полное имя доп. формы. И для этого можно использовать вот такую небольшую функцию:
&НаКлиенте
Функция ПолноеИмяФормы(НужноеИмя) Экспорт
НекийМассив = СтрРазделить(ИмяФормы, ".", Ложь);
НекийМассив[НекийМассив.ВГраница()] = НужноеИмя;
Возврат СтрСоединить(НекийМассив, ".");
КонецФункции